V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
tw93
V2EX  ›  分享创造

你不知道的 Agent:原理、架构与工程实践

  •  
  •   tw93 ·
    Tw93 · 3 月 30 日 · 1148 次点击
    Agent 架构封面图

    0. 太长不读

    在写完「你不知道的 Claude Code:架构、治理与工程实践」之后,发现自己对 Agent 底层的理解还不够深入,加上团队在 Agent 方向已经有不少业务落地经验,一直缺少一份系统梳理,所以我又把资料、开源实现和自己写的代码一起过了一遍,最后整理成了这篇文章。

    这篇文章主要讲 Agent 架构里几块最影响工程效果的内容,包括控制流、上下文工程、工具设计、记忆、多 Agent 组织、评测、追踪和安全,最后再用 OpenClaw 的实现把这些设计原则串起来看一遍。

    整理下来,有几处判断和我原来想的不太一样,更贵的模型带来的提升,很多时候没有想象中那么大,反而 Harness 和验证测试质量对成功率的影响更大,调试 Agent 行为时,也应优先检查工具定义,因为多数工具选择错误都出在描述不准确,另外,评测系统本身的问题,很多时候比 Agent 出问题更难发现,如果一直在 Agent 代码上反复调,效果未必明显,读完这篇,这几个问题应该能有些答案。


    1. Agent Loop 的基本运转方式

    Agent Loop 的核心实现逻辑抽象后其实不到 20 行代码:

    const messages: MessageParam[] = [{ role: "user", content: userInput }];
    
    while (true) {
      const response = await client.messages.create({
        model: "claude-opus-4-6",
        max_tokens: 8096,
        tools: toolDefinitions,
        messages,
      });
    
      if (response.stop_reason === "tool_use") {
        const toolResults = await Promise.all(
          response.content
            .filter((b) => b.type === "tool_use")
            .map(async (b) => ({
              type: "tool_result" as const,
              tool_use_id: b.id,
              content: await executeTool(b.name, b.input),
            }))
        );
        messages.push({ role: "assistant", content: response.content });
        messages.push({ role: "user", content: toolResults });
      } else {
        return response.content.find((b) => b.type === "text")?.text ?? "";
      }
    }
    

    对应的控制流如下,感知 -> 决策 -> 行动 -> 反馈四个阶段不断循环,直到模型返回纯文本为止:

    Agent Loop 控制流

    看过不少 Agent 实现和官方 SDK ,结构都差不多,循环本身相当稳定,从最小实现一路扩展到支持子 Agent 、上下文压缩和 Skills 加载,主循环基本没有变化,新增能力通常都是叠加在循环外部,而不是改动循环内部。

    新能力基本只通过三种方式接入:扩展工具集和 handler 、调整系统提示结构、把状态外化到文件或数据库,不应该让循环体本身变成一个巨大的状态机,模型负责推理,外部系统负责状态和边界,一旦这个分工确定下来,核心循环逻辑就很少需要频繁调整了。

    Workflow 和 Agent 有什么区别

    Anthropic 对这两类系统有一个直接区分:执行路径由代码预先写死的是 Workflow ,由 LLM 动态决定下一步的是 Agent ,核心区别在于控制权掌握在谁手里,现实中很多标着 Agent 的产品,深入看其实更接近 Workflow ,不过两者本身并无高下之分,真正重要的是给任务找到更适合的解决方案。

    维度 Workflow Agent
    控制权 代码预定义,同输入必走同一路径 LLM 动态决策,可能需要评测验证
    执行方式 工具顺序固定,错误走预设分支 工具按需选择,模型可尝试自我修复
    状态与记忆 显式状态机,节点跳转清晰 隐式上下文,状态在对话历史中累积
    维护成本 改流程需修改代码并重新部署 调整系统提示即可,无需重新部署
    可观测性 日志定位节点,延迟可预估 需完整执行记录理解决策链,轮数不固定
    人机协作 人在预设节点介入 人在任意轮次介入或接管
    适用场景 流程固定、输入边界清晰 需要中间推理与灵活判断

    放在一张图里看,会更直观:

    Workflow 与 Agent 对比

    五种常见控制模式

    大多数 AI 系统拆开看,其实都是这五种模式的组合,很多场景并不需要完整的 Agent 自主权,把其中几种模式搭起来就够了,关键还是看任务本身适合哪一种设计。

    1. 提示链 Prompt Chaining:任务拆成顺序步骤,每步 LLM 处理上一步的输出,中间可加代码检查点,适合生成后翻译、先写大纲再写正文这类线性流程。

    2. 路由 Routing:对输入分类,定向到对应的专用处理流程,简单问题走轻量模型,复杂问题走强模型,技术咨询和账单查询走不同逻辑。

    3. 并行 Parallelization:两种变体:分段法把任务拆成独立子任务并发跑,投票法把同一任务跑多次取共识,适合高风险决策或需要多视角的场景。

    4. 编排器-工作者 Orchestrator-Workers:中央 LLM 动态分解任务,委派给工作者 LLM ,综合结果,nanobot 的 spawn 工具和 learn-claude-code 的子 Agent 模式都是这个原型。

    5. 评估器-优化器 Evaluator-Optimizer:生成器产出,评估器给反馈,循环直到达标,适合翻译、创意写作这类质量标准难以用代码精确定义的任务。

    五种常见控制模式

    2. 为什么 Harness 比模型更关键

    Harness 是指围绕 Agent 构建的测试、验证与约束基础设施,这里的 Harness 至少包括四个部分:验收基线、执行边界、反馈信号和回退手段。

    模型虽然重要,但决定系统能不能稳定运行的,往往是这些外围工程条件。这个判断在代码编写这类高可验证任务上最成立,但在开放式研究、多轮协商这类弱验证任务里,模型上限本身仍然更关键。

    OpenAI 的 Agent 优先开发实践

    3 个工程师 5 个月写了百万行代码,将近 1500 个 PR ,是传统开发速度的 10 倍。这个速度背后不是模型有多强,而是几个工程决策做对了:

    1. Agent 看不到的内容等于不存在:知识必须存在于代码库本身,外部文档对运行中的 Agent 不可见,AGENTS.md 只保留约 100 行作为索引,细节拆到各 docs 目录按需引用。
    2. 约束编码化而非文档化:写在文档里的规范很容易被忽略,编码进 Linter 、类型系统或 CI 规则里的约束才具备可执行性,架构分层靠自定义 Linter 机械强制,不靠人工 Review 。
    3. Agent 端到端自主完成任务:从验证当前状态、复现 Bug 、实现修复、驱动应用验证,到开 PR 、处理 Review 反馈、自主合并,全链路不需要人介入,查日志、查指标、查追踪都由 Agent 主动完成。
    4. 最小化合并阻力:测试偶发失败用重跑处理而不是阻塞进度,在高吞吐环境下等待人工审查的成本往往高于修复小错误的成本。写代码的纪律没有消失,只是从人工 Review 变成了机器执行的约束,一次写进去,到处生效。
    Codex 可观测性栈

    APP 把日志、指标、追踪三路数据经由 Vector 分发到 Victoria 存储层,对应 LogQL 、PromQL 、TraceQL 三个查询接口,Codex 通过这三个接口查询、关联、推理,完成改动后重启应用、重跑工作负载,结果再打回给 Codex ,UI Journey 也作为输入接入。整套可观测性栈按任务临时创建、任务完成即销毁,Agent 不需要等人告知错误,直接查询系统状态验证修改是否生效。

    Harness 的关键结论是什么

    Harness 关键结论

    图里用任务清晰度和验证自动化程度把任务分成四种状态,右上角目标明确、结果可以自动验证,是最适合 Agent 发挥的区域,左上角任务清楚但验收还得人盯,吞吐量天花板是人的审查速度,右下角有自动化反馈但目标模糊,系统会高效地往错误方向跑,左下角两者都缺,Agent 基本起不到作用。

    Harness 要做的就是把任务推进右上角,让对错有机器可以执行的判断标准,而不是靠人盯。


    3. 上下文工程为什么决定稳定性

    Transformer 的注意力复杂度是 $O(n^2)$,上下文越长,关键信号越容易被噪声稀释,实践里最常见的失效模式是无关内容一旦占到上下文的大头,Agent 的决策质量就会明显下滑,这类现象通常被叫作 Context Rot ,很多看起来像模型能力不足的问题,往往可以追溯到上下文组织不当。

    上下文为什么要分层

    问题通常不是窗口不够长,而是信息密度不对,偶尔用的东西每次都加载进来,稳定的规则和动态的状态混在一起,模型能看到的内容越来越多,但真正有用的部分越来越难被注意到。

    上下文分层结构

    解决方式是按信息的使用频率和稳定性分层管理,每层只放自己该放的东西:

    • 常驻层:身份定义、项目约定、绝对禁止项,每次会话都必须成立的内容,保持短、硬、可执行
    • 按需加载:Skills 和领域知识,描述符常驻,完整内容触发时再注入,不用的不占位置
    • 运行时注入:当前时间、渠道 ID 、用户偏好等动态信息,每轮按需拼入
    • 记忆层:跨会话经验写入 MEMORY.md,不直接进系统提示,需要时才读取
    • 系统层:Hooks 或代码规则处理确定性逻辑,完全不进上下文

    别把确定性逻辑放进上下文,凡是可以通过 Hooks 、代码规则或工具约束表达的内容,都应交给外部系统处理,而不是让模型反复读取。

    三种常见压缩策略

    策略 成本 丢什么 适用场景
    滑动窗口 极低 早期上下文 简短对话
    LLM 摘要 细节,保留决策 长任务、含关键决策
    工具结果替换 极低 工具原始输出 工具调用密集型

    滑动窗口实现最简单,但会丢掉早期决策背景。LLM 摘要的进阶做法是 branch summarization ,摘要时明确保留架构决策、未完成任务和关键约束。工具结果替换里,micro_compact 每轮替换旧工具输出,auto_compact 在上下文超阈值时自动触发。

    Prompt Caching 减少重复开销

    LLM 推理时,Transformer attention 会为每个 token 计算 Key-Value 对,如果当前请求的输入前缀和之前某次请求完全一致,这部分 KV 就不需要重新计算,直接从缓存读取,这就是 Prompt Caching 的底层原理。命中的前提是精确前缀匹配,不是内容相似就能触发,任何一个 token 不同都会破坏匹配,所以缓存友好的设计核心是稳定性,系统提示、工具定义、长文档这类在多轮请求里基本不变的内容天然适合缓存,动态信息(当前时间、用户输入、工具调用结果)放在后面,不影响前缀的稳定性。

    这和上下文分层设计直接相关。常驻层越稳定,前缀命中率越高,边际成本越低,所以「常驻层短而稳定」不只是为了节省 token ,也在保护缓存命中。Skills 延迟加载的好处也在这里,按需注入的内容不破坏系统提示前缀,而是追加在稳定前缀之后,工具定义同样参与缓存计算,接了很多 MCP 工具的 Agent 如果工具集频繁变动,缓存命中就会不断失效。有一个反直觉的地方:稳定的大系统提示,比频繁变动的小提示实际成本更低,因为写入成本只付一次,后续每次调用读取的折扣可以达到 90%。

    为什么 Skills 要按需加载

    Skills 是上下文工程里非常有效的一种模式,核心思路是:系统提示只保留索引,完整知识按需加载

    const systemPrompt = `
    可用 Skills:
    - deploy: 部署到生产环境的完整流程
    - code-review: 代码审查检查清单
    - git-workflow: 分支策略和 PR 规范
    `;
    
    async function executeLoadSkill(name: string): Promise<string> {
      return fs.readFile(`./skills/${name}.md`, "utf-8");
    }
    

    Skill 描述要足够短,避免常驻上下文持续涨 token ,也要足够像路由条件而不是功能介绍,至少说明什么时候用、什么时候不要用、产出物是什么,最直接的写法是 Use when / Don't use when 再补几条反例,很多路由失败不是模型能力问题,而是边界写得不清楚。系统提示里也要把调用规则写明确:每次回复前先扫描 available_skills,有明确匹配时再读取对应 SKILL.md,多个匹配时优先选最具体的那个,没有匹配就不读取,一次只加载一个。

    Skills 按需加载

    图里的数据很直接:没有反例时准确率从基准 73% 掉到 53%,加上反例后升到 85%,响应时间还降了 18.1%。反例不是可选项,是 Skill 描述能不能起作用的关键。

    Skills 不能等 Agent 想起来再用,要每轮都先扫描描述,但扫描成本要足够低,实际加载数量也要受控,如果 Skill 会触发外部 API 写操作,系统提示里应显式补充速率限制要求,尽量批量写入、避免逐条循环、遇到 429 主动等待。

    Skill 描述符有两个写法陷阱值得单独说。第一个是字数:

    # 低效(约 45 tokens )
    description: |
      This skill handles the complete deployment process to production.
      It covers environment checks, rollback procedures, and post-deploy
      verification. Use this before deploying any code to production.
    
    # 高效(约 9 tokens )
    description: Use when deploying to production or rolling back.
    

    路由准确率差距不大,但每个启用的 Skill 描述符都常驻上下文,Skill 一多,长描述的累积成本很可观。第二个是精度:描述太短(help with backend)等于任何后端工作都能触发,路由会乱。真正有效的描述符是路由条件,不是功能介绍,"何时该用我"比"我能做什么"重要得多。

    数量上同样要控制:常驻系统提示的只放高频 Skill ,低频的不要塞进默认列表,需要时再手动引入,极低频的直接用文档替代就够了,不必做成 Skill 。几个典型反模式:正文几百行工作手册全塞进 Skill 正文而不是拆成 supporting files ;一个 Skill 试图覆盖 review 、deploy 、debug 、incident 五件事;有副作用的 Skill 没有显式限制调用时机。这三个问题都会让 Skill 路由失准,而且很难排查。

    Skills 和 MCP 在上下文成本上的特征并不相同,很多 MCP 会把完整结果直接返回给模型,更容易迅速吃掉上下文预算,CLI + 单句描述的 Skill 更接近模型熟悉的调用方式,在大多数可过滤、可拼接的数据读取任务里也更简洁,当然 MCP 也有明确适用场景,例如 Playwright 这类需要维护状态的任务。

    压缩最容易丢掉什么

    压缩阶段最常见的问题,不是摘要不够短,而是保留顺序设错了,LLM 通常会优先删除那些看起来还可以重新获取的信息,早期的 tool output 通常最先被移除,但与之相关的架构决策、约束理由和失败路径也很容易一并丢失。最好在 CLAUDE.md 或等价文档里明确写出压缩时的保留优先级:

    ### Compact Instructions 如何保留关键信息
    
    保留优先级:
    
    1. 架构决策,不得摘要
    2. 已修改文件和关键变更
    3. 验证状态,pass/fail
    4. 未解决的 TODO 和回滚笔记
    5. 工具输出,可删,只保留 pass/fail 结论
    

    压缩时还有一条容易踩的坑:不要改动标识符,UUID 、hash 、IP 、端口、URL 、文件名这类值必须原样保留,一旦把 PR 编号或 commit hash 改错一位,后续工具调用就会直接失效。

    文件系统为什么适合做上下文接口

    Cursor 把这种方式叫 Dynamic Context Discovery ,默认少给,只在需要时读取。文件系统天然适合做这个接口,工具调用经常返回大量 JSON ,几次搜索就能堆出成千上万 token ,不如直接写入文件,让 Agent 通过 grep 、rg 或脚本按需读取,工具写文件,Agent 读文件,开发者也可以直接查看。

    Cursor 在 MCP 工具上也验证过这个方向:他们把工具描述同步到文件夹,Agent 默认只看到工具名,需要时再查询具体定义,A/B 测试中,调用 MCP 工具的任务总 token 消耗减少了 46.9%。

    同样的思路也适用于长任务压缩,压缩触发时,不直接丢弃历史,而是把聊天记录完整保留为文件,摘要里只引用文件路径,后续如果 Agent 发现摘要缺少细节,仍然可以回到历史文件里检索,这样压缩就变成了一种有损但可追溯的操作,而不是一次不可恢复的硬截断。


    4. 工具设计决定 Agent 能做什么

    上下文决定模型能看到什么,工具决定模型能做什么。工具定义的质量比数量更关键,仅 5 个 MCP 服务器就可能带来约 55,000 tokens 的工具定义开销,相当于在 200K 上下文里还没开始对话就用掉了近三成,工具一旦过多,模型对单个工具的注意力也会被稀释。

    工具问题多数不在数量不够,而在选不对、描述看不懂、返回一堆没用的、出了错 Agent 也不知道怎么改。

    维度 好工具 差工具
    粒度 对应 Agent 要完成的目标 对应 API 能做的操作
    示例 update_yuque_post get_post + update_content + update_title
    返回 与下一步决策直接相关的字段 完整原始数据
    错误 结构化,含修正建议 通用字符串 "Error"
    描述 说明何时用、何时不用 只写功能说明

    工具设计如何演进

    工具设计大致经历了三个阶段,早期做法是直接把现有 API 封装成工具扔给模型,后来发现模型选错工具,问题不在模型能力,而在工具本身的设计视角就错了,原来是给工程师设计的,不是给 Agent 设计的。

    第一代,API 封装:每个 API Endpoint 对应一个工具,粒度过细,Agent 往往需要协调多个工具才能完成一个目标。

    第二代,ACI ,即 Agent-Computer Interface:工具应对应 Agent 的目标,而不是底层 API 操作,不要只给一个像 update(id, content) 这样的通用接口,而是直接给一个 update_yuque_post(post_id, title, content_markdown),一次把目标动作说完整。

    第三代,Advanced Tool Use:在工具设计之上,进一步优化工具的发现、调用和描述方式,主要包括三个方向:

    • Tool Search ,动态工具发现:别把全部工具定义一次性塞给模型,Agent 通过 search_tools 按需发现工具定义,上下文保留率可达到 95%,Opus 4 的准确率也从 49% 提升到 74%。

    • Programmatic Tool Calling ,代码编排:别让中间数据一轮轮穿过模型,而是让模型用代码编排多个工具调用,中间结果在执行环境中流转,不进入 LLM 上下文,token 消耗可从约 150,000 降到约 2,000 。

    • Tool Use Examples ,示例驱动:每个工具附带 1-5 个真实调用示例,JSON Schema 只能描述参数类型,但无法表达调用方式,加入示例后,工具调用准确率可从 72% 提升到 90%。


    ACI 工具设计有哪些原则

    类比 HCI 对人的影响,工具设计对 Agent 的影响一样直接,不能只看「工具能不能调用」,还要看「调用错了之后能不能自己修回来」。

    三个原则放在一起看更清楚,差的做法参数模糊、错误不可修正、定义实现分离:

    // 差:参数模糊,出错只返回字符串,Agent 不知道怎么修正
    const tool = {
      name: "update_yuque_post",
      input_schema: {
        properties: {
          post_id: { type: "string" },
          content: { type: "string" },
        },
      },
    };
    // 出错时
    return "Error: update failed";
    

    好的做法用 betaZodTool 把定义和实现绑在一起,参数描述直接约束格式,错误结构化给出修正建议:

    const updateTool = betaZodTool({
      name: "update_yuque_post",
      description: "更新语雀文章内容,不适合创建新文章",
      inputSchema: z.object({
        post_id: z.string().describe("语雀文章 ID ,纯数字字符串,如 '12345678'"),
        title: z.string().optional().describe("文章标题,不改时可省略"),
        content_markdown: z.string().describe("Markdown 格式正文"),
      }),
      run: async (input) => {  // input 类型自动推导,问题尽量在编译期暴露
        const post = await getPost(input.post_id);
        if (!post) throw new ToolError("文章 ID 不存在", {
          error_code: "POST_NOT_FOUND",
          suggestion: "请先调用 list_yuque_posts 获取有效的 post_id",
        });
        return await updatePost(input.post_id, input.title, input.content_markdown);
      },
    });
    
    ACI 工具设计对比:差工具设计会让 Agent 反复绕圈,好工具设计能让 Agent 更快选对并修正错误

    左边是差工具设计,工具只说自己能做什么,不说明什么时候该用、什么时候不该用,结果是 Agent 容易选错工具、填错参数,报错后不断重试绕圈,右边是符合 ACI 原则的工具设计,边界清楚、结构化错误给出修正建议,Agent 更容易一次选对,失败后也能快速修正。

    调试 Agent 时应先检查工具定义,大多数工具选择错误的原因出在描述不准确,不在模型能力,工具数量也要克制,能用 Shell 处理的、只需静态知识的、更适合 Skill 的,都不需要新增工具。

    为什么工具消息也要隔离

    框架运行过程中会产生一些内部事件:压缩发生了、通知推送了、某个工具调用被跳过了,这些事件需要记在会话历史里,但不应该直接进 LLM ,否则模型会看到一堆它不理解的字段,白白消耗 token 。

    解决方式是在框架层分两种消息类型:给应用层用的 AgentMessage 可以携带任意自定义字段,真正发给 LLM 的 Message 只保留 userassistanttool_result 三种标准类型,调用前过滤一遍,会话历史保留完整框架状态,LLM 只收它需要的部分。


    5. 记忆系统如何设计

    Agent 不具备原生的时间连续性,会话结束后,上下文随之清空,下一次启动时也不会自动保留此前状态,要让系统具备跨会话的一致性,记忆层得单独设计,对 Agent 来说它是一层基础设施,不是可以事后补上的能力。

    四种记忆分别存在哪里

    这里不是按存储介质来分,而是按 Agent 实际要解决的问题来分:

    • 上下文窗口,工作记忆:当前任务所需的最小信息,token 有限,得主动管理
    • Skills ,程序性记忆:怎么做某件事,操作流程、领域规范,按需加载不默认常驻
    • JSONL 会话历史,情景记忆:发生了什么,磁盘持久化,支持跨会话检索
    • MEMORY.md,语义记忆:Agent 主动写入认为重要的事实,每次启动时注入系统提示
    四种记忆类型与存储位置:上下文窗口位于运行时 messages[],Skills 、JSONL 会话历史和 MEMORY.md 位于磁盘,生命周期和注入方式各不相同

    左侧是 Agent 运行时,只有上下文窗口存在于 messages[] 中,会随着会话结束一起清空,右侧是磁盘上的持久层,Skills 文件按需加载,JSONL 会话历史保留完整过程并支持检索,MEMORY.md 则沉淀 Agent 主动写入的稳定事实,并在后续会话中持续注入。

    MEMORY.md 和 Skills 如何协作

    实际系统实现方式不同,但核心都在解决两件事:重要事实要留下来,注入模型的内容又不能失控。

    ChatGPT 四层记忆

    拿它当一个产品实现来看,它没有使用向量数据库,也没有引入 RAG 检索增强生成,整体结构比很多人的预期更简洁:

    内容 持久化
    Session Metadata 设备、地点、使用模式 否,会话级
    User Memory 约 33 条关键偏好事实 是,每次注入
    Conversation Summary 约 15 个最近对话的轻量摘要 是,摘要预生成
    Current Session 当前对话滑动窗口

    OpenClaw 混合检索

    • memory/YYYY-MM-DD.md,追加写日志,保留原始细节
    • MEMORY.md,精选事实,Agent 主动维护
    • memory_search,70% 向量相似度 + 30% 关键词权重的混合检索

    这个设计的好处是可读、可改、可检索,Markdown 文件可以直接查看和修订,搜索时按相关性拉取需要的内容,而不是把全部记忆一次性塞进上下文,对大多数 Agent 来说,记忆库规模并不需要一开始就引入向量存储,结构化 Markdown 加关键词搜索已经具备足够好的可调试性、可维护性和成本表现,只有当规模超过几千条、并且确实需要语义相似度检索时,再考虑引入向量检索会更合适。

    记忆整合如何触发并回退

    有了记忆分层之后,下一步要处理的就不是「要不要存」,而是「什么时候整合,以及整合失败怎么办」。

    记忆整合与回退流程:消息流在 token 使用率超过阈值后触发整合,成功时摘要写入 MEMORY.md 并移动整合指针,失败时原始消息写入 archive/ 保留完整历史

    这张图强调的不是「把旧消息删掉」,而是把它们从活跃上下文中安全移出,左边是持续增长的对话消息流,中间用 tokenUsage / maxTokens >= 0.5 作为触发阈值,达到阈值后,成功路径会先对待整合消息做 llmSummarize(toConsolidate),再把摘要追加到 MEMORY.md,最后只更新 lastConsolidatedIndex,失败路径则把原始消息写入 archive/,保留完整历史,避免整合失败时丢失上下文。

    最关键的不是摘要写得多漂亮,而是流程本身必须可回退,系统只移动指针,不删除原始消息,即使整合失败,也还能回到原始存档继续工作。

    6. 如何逐步放开 Agent 自主度

    这里说的自主度,不是少几次人工确认,而是让 Agent 能在更长时间跨度内稳定推进任务,前提也不是直接放权,而是先补齐三类基础设施:跨 session 续跑、单个 session 内的进度约束,以及慢速 I/O 的后台接入。

    长任务如何跨 session 继续

    长任务最常见的失败,不是单步报错,而是 session 结束时任务还没做完,即使启用 compaction ,也挡不住两类问题:一是在单个 session 里试图做完整个应用,结果上下文先耗尽,二是只做完一部分,下一轮又无法准确恢复现场,过早判断完成。

    更稳定的做法,是把长任务拆成 Initializer Agent 和 Coding Agent 两个角色协作,这种模式最适合代码生成、应用搭建、重构迁移这类单个 session 做不完、但又能拆成一批可验证子任务的工作。

    Initializer Agent 只在第一轮运行一次,负责生成 feature-list.jsoninit.sh、初始 git commit 和 claude-progress.txt,先把任务变成可持久化的外部状态,后面的多个 session 由 Coding Agent 循环执行,每次从 claude-progress.txtgit log 恢复现场,定位当前任务,实现一个功能,跑测试,更新 passes 字段,提交代码后退出,这样即使中途崩溃,也能直接从文件系统里的状态继续,而不是从头再来。

    Initializer + Coding Agent 跨 session 协作流程:Initializer 只运行一次并生成 feature-list.json 、init.sh 、初始 commit 和 claude-progress.txt ,后续 Coding Agent 在多个 session 中通过文件系统恢复状态、实现单个功能、测试、更新 passes 并提交代码

    进度要放在文件里,不要放在上下文里,功能清单用 JSON ,不用 Markdown ,结构化格式更适合模型稳定修改,当 feature-list.json 里所有功能都变成 passes: true,任务才算完成。


    又又又放不下了,可以去这里阅读我的原文,当然假如你觉得我的内容还行,也可以关注我

    https://x.com/HiTw93/status/2034627967926825175

    6 条回复    2026-03-31 23:30:00 +08:00
    zisen
        1
    zisen  
       3 月 30 日
    bro 说点大伙不知道的,这种在知乎都看烂了
    yusf
        2
    yusf  
       3 月 30 日
    @zisen 这种类型的知识,现在都属于大伙都看烂的级别吗?
    qq007523
        3
    qq007523  
       3 月 30 日
    概念、方法论、设计模式大家都懂,有 github demo 看看嘛
    Paul0218
        4
    Paul0218  
       3 月 30 日
    多发,爱吃
    Ziuc
        5
    Ziuc  
       3 月 31 日
    配图很漂亮,请问是用什么工具绘制的?
    heyshark
        6
    heyshark  
       3 月 31 日
    正好在学习大模型方法论相关知识,先点个赞再看
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   894 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 21:40 · PVG 05:40 · LAX 14:40 · JFK 17:40
    ♥ Do have faith in what you're doing.