<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>状态管理 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/</link><description>Recent content in 状态管理 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 09 Jun 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/index.xml" rel="self" type="application/rss+xml"/><item><title>第7章：状态管理算法</title><link>https://amatsuzero.github.io/LastStand/posts/aiagentalgorithm/chapter-07/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/aiagentalgorithm/chapter-07/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;程序的本质就是状态与状态之间的转换。&amp;rdquo; —— Edsger W. Dijkstra&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="71-问题引入百态纷呈的-agent-系统"&gt;7.1 问题引入：百态纷呈的 Agent 系统&lt;/h2&gt;
&lt;p&gt;想象一个拥有超过 100 个状态属性的 AI Agent 系统。它需要同时管理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;对话历史&lt;/strong&gt;：数十轮多模态消息，包含用户输入、模型回复、工具调用结果&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具权限&lt;/strong&gt;：每个工具的授权模式（允许、拒绝、询问），可在运行时动态变更&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用户配置&lt;/strong&gt;：来自用户设置、项目设置、企业策略、命令行参数等多层级配置源&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI 状态&lt;/strong&gt;：展开/折叠视图、模型选择、通知队列、输入提示等&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;任务状态&lt;/strong&gt;：后台任务的生命周期、子 Agent 的运行状态、团队协作信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会话元数据&lt;/strong&gt;：会话 ID、权限模式、远程连接状态、推测执行状态&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当多个组件同时读写这些状态时，如何确保变更可预测、不产生副作用？当配置文件在磁盘上被外部修改时，如何实时感知并正确合并？当会话中断后恢复时，如何从持久化的日志中重建完整状态？&lt;/p&gt;
&lt;p&gt;这些问题的本质是一个经典的工程挑战：&lt;strong&gt;在复杂系统中实现可预测的状态管理&lt;/strong&gt;。Claude Code 源码为我们展示了一套精巧的解决方案——它融合了不可变状态机、发布-订阅、选择器订阅、层级合并、事件溯源等多种算法思想，构建了一个既高效又可靠的状态管理体系。&lt;/p&gt;
&lt;h2 id="72-算法思想"&gt;7.2 算法思想&lt;/h2&gt;
&lt;h3 id="721-不可变状态机算法"&gt;7.2.1 不可变状态机算法&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;核心原则：状态只能通过纯函数转换，旧状态永不修改。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不可变状态机的思想源自函数式编程：给定当前状态 S 和一个转换函数 f，新状态 S&amp;rsquo; = f(S)。旧状态 S 在转换过程中不被修改，它依然可以被引用和比较。这一原则带来三大好处：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;变更检测极其廉价&lt;/strong&gt;——只需 &lt;code&gt;Object.is(prev, next)&lt;/code&gt; 即可判断是否发生变更，时间复杂度 O(1)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不存在并发修改的竞态条件&lt;/strong&gt;——因为没有人能修改已经发出的状态快照&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;天然支持时间旅行&lt;/strong&gt;——旧状态快照可以保留，用于调试或回溯&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Claude Code 在类型层面通过 &lt;code&gt;DeepImmutable&amp;lt;T&amp;gt;&lt;/code&gt; 泛型强制保证不可变性。AppState 的核心字段被 &lt;code&gt;DeepImmutable&lt;/code&gt; 包裹，编译器会阻止任何对深层属性的直接赋值。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;//&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;类型层面的不可变保证&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;type AppState &lt;span style="color:#f92672"&gt;=&lt;/span&gt; DeepImmutable&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; settings: SettingsJson
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; verbose: boolean
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mainLoopModel: ModelSetting
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; toolPermissionContext: ToolPermissionContext
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;//&lt;/span&gt; &lt;span style="color:#f92672"&gt;...&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;//&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;少数包含函数类型的字段排除在&lt;/span&gt; DeepImmutable &lt;span style="color:#960050;background-color:#1e0010"&gt;之外&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tasks: { [taskId: string]: TaskState }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mcp: { clients: MCPServerConnection[]; tools: Tool[]; &lt;span style="color:#f92672"&gt;...&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意 &lt;code&gt;DeepImmutable&lt;/code&gt; 与交叉类型 &lt;code&gt;&amp;amp;&lt;/code&gt; 的组合使用：核心配置字段（settings、verbose、权限上下文等）被严格冻结；而包含回调函数或可变引用的字段（tasks、mcp）则排除在外。这是&lt;strong&gt;实用主义的不可变性&lt;/strong&gt;——在类型安全和运行时灵活性之间取得平衡。&lt;/p&gt;</description></item><item><title>状态管理</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/vue/vue-019/</link><pubDate>Sat, 05 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/vue/vue-019/</guid><description>&lt;p&gt;本知识点将以 &lt;code&gt;Pinia&lt;/code&gt; 为例，介绍 Vue 中的状态管理。&lt;/p&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://pinia.vuejs.org/zh/"&gt;Pinia&lt;/a&gt;简称小菠萝🍍，是一个专为Vue 3设计的现代化状态管理库，为&lt;code&gt;Vue 3&lt;/code&gt;开发的，它提供了一种简单、可扩展和类型安全的方式来管理应用程序的状态。&lt;/p&gt;
&lt;p&gt;与&lt;code&gt;Vue 2&lt;/code&gt;中的Vuex相比，&lt;code&gt;Pinia&lt;/code&gt;提供了更好的&lt;code&gt;TypeScrip&lt;/code&gt;t支持，具有更好的类型定义和类型推断，可在编译时捕获错误，提供更高的代码可靠性和开发体验。它是专为&lt;code&gt;Vue 3&lt;/code&gt;设计的，充分利用了&lt;code&gt;Vue 3&lt;/code&gt;的新特性，如&lt;code&gt;Composition API&lt;/code&gt;，以提供更直接、自然和灵活的状态管理体验。&lt;code&gt;Pinia&lt;/code&gt;的核心概念是&lt;code&gt;Store&lt;/code&gt;，它类似于&lt;code&gt;Vuex&lt;/code&gt;中的模块，用于管理应用程序的状，可以将相关的状态和逻辑组合到单个&lt;code&gt;Store&lt;/code&gt;中，使代码更清晰、结构更有组织性。除此之外海提供了许多有用的特性和功能，例如模块化组织、状态持久化、插件扩展等。&lt;/p&gt;
&lt;p&gt;总的来说，&lt;code&gt;Pinia&lt;/code&gt;是一个功能强大而灵活的状态管理解决方案，适用于各种规模的&lt;code&gt;Vue 3&lt;/code&gt;应用程序。它提供了现代化的特性和工具，帮助我们更好地组织、管理和扩展应用程序的状态，同时提供了更好的类型安全和开发体验。&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;p&gt;运行安装命令&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install pinia
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在&lt;code&gt;main.ts&lt;/code&gt;中引入&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// main.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt; } &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;vue&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createPinia&lt;/span&gt; } &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;pinia&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;App&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./App.vue&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pinia&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createPinia&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createApp&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;App&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;use&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;pinia&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;mount&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#app&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="初始化store"&gt;初始化Store&lt;/h2&gt;
&lt;p&gt;新建&lt;code&gt;stores&lt;/code&gt;文件，用于存放所有的&lt;code&gt;store&lt;/code&gt;，然后创建&lt;code&gt;index.ts&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;同过 &lt;code&gt;defineStore()&lt;/code&gt; 定义一个&lt;code&gt;store&lt;/code&gt;，它接受一个参数作为仓库名称，也就是&lt;code&gt;Id&lt;/code&gt;。它返回一个函数，默认我们使用&lt;code&gt;user&lt;/code&gt;开头的风格来接收。第二个参数为一个&lt;code&gt;Setup&lt;/code&gt;函数或者&lt;code&gt;Option&lt;/code&gt;对象。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;defineStore&lt;/span&gt; } &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;pinia&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;useUsersStore&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;defineStore&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;users&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 其他配置...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="option-store"&gt;Option Store&lt;/h2&gt;
&lt;p&gt;这种方式熟悉&lt;code&gt;Vuex&lt;/code&gt;的很了解，传入一个带有 &lt;code&gt;state&lt;/code&gt;、&lt;code&gt;actions&lt;/code&gt; 与 &lt;code&gt;getters&lt;/code&gt; 属性的 &lt;code&gt;Option&lt;/code&gt; 对象&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;userUsersStore&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;defineStore&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;users&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; () &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;inkun&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;current&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;getters&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;🐔你好帅&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;actions&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;getUserInfo&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 &lt;code&gt;Option Store&lt;/code&gt; 中：&lt;/p&gt;</description></item></channel></rss>