加载中...
  • 六大支柱地图:为什么不同 Agent 产品仍然有共同骨架 loading

    吃透 AI Agent 开发 · 第 03 篇 · 第一章 · 认知校准

    Claude Code、Cursor、Manus 看起来差异很大,但都在处理同一组问题:循环、工具、上下文、记忆、协作和 Harness。

    Claude Code、Cursor、Manus 看起来差异很大,但都在处理同一组问题:循环、工具、上下文、记忆、协作和 Harness。

    先做一次“换皮测试”

    把产品名字暂时遮住,只留下一个任务:“读三份项目文件,提出修改方案,得到确认后再写入”。如果一个系统能回答模型看到了什么、哪一步允许写入、长结果放在哪里、失败后怎样继续,它就拥有一副可解释的骨架;如果只能说“框架内部会处理”,那只是把复杂度藏起来。

    同一个 Agent 换成客服、代码助手或研究助手,输入和工具会变,六类责任不会凭空消失。Loop 负责推进,Tool System 负责副作用,Context 负责信息取舍,Memory 负责跨轮事实,Multi-Agent 负责分工,Harness 负责把它们装成可运行的产品。把这六个词当作检查问题,比背产品术语更耐用。

    六个支柱不是六个目录

    下面的图不是推荐的文件夹结构,而是一张“谁对什么负责”的地图。一个项目可以把 Loop 和 Context 写在同一个模块,也可以把 Memory 存成文件;只要交接对象和失败责任清楚,物理目录怎么排都不是关键。

    flowchart TB
      Request[任务与约束] --> Loop[Agent Loop]
      Loop --> Context[Context Engineering]
      Loop --> Tools[Tool System]
      Tools --> State[状态与证据]
      State --> Memory[Memory]
      Loop --> Team[Multi-Agent]
      Context --> Harness[Harness]
      Tools --> Harness
      Memory --> Harness
      Team --> Harness
    

    Loop:让“下一步”有来源

    Loop 不是 while 循环的别名,而是一次次把模型判断、工具结果、取消信号和停止理由串起来的协议。它要能回答:本轮请求带着哪些消息进入模型?模型返回了文本还是工具意图?工具完成后,什么事实被追加进下一轮?什么时候结束,谁决定结束?

    Tool System:把意图挡在副作用前面

    工具层的职责不是把函数挂到对象上,而是把 schema、参数校验、权限、Hook、超时、审计和结果协议放进同一条入口。模型可以提出“删除这个文件”的意图,但不能凭一句自然语言绕过路径检查。

    Context 与 Memory:同一份信息不代表同一种生命周期

    当前任务中的文件摘要适合放进动态上下文,用户明确要求长期保存的偏好才可能进入 Memory。两者都叫“上下文”时最容易互相污染:压缩后的摘要被当成事实,旧项目记忆被当成当前指令,最后模型看似知道更多,实际更难判断哪些内容可信。

    Multi-Agent 与 Harness:扩大能力也扩大控制面

    拆成多个 Agent 不会自动获得并行收益。子任务需要输入边界、权限、完成标准和结果句柄;Harness 则负责配置、会话、日志、恢复、界面和版本变更。没有 Harness,演示里的 Agent 很聪明,部署后的 Agent 却无法重放。

    用三个产品假设做比较

    观察角度 代码助手 客服助手 研究助手
    最贵的错误 改错文件或越权执行 给出过期或未经授权的承诺 把推测写成有来源的事实
    最重要的支柱 Tool System、Loop Context、Memory Context、Evidence、Eval
    必须留下的证据 diff、路径、审批 引用版本、用户确认 文档来源、检索片段、置信度
    不能交给模型独自决定 写入范围和停止条件 权限和赔付规则 结论是否足够可靠

    这张比较的用处,是提醒我们不要照搬别人的目录。代码助手把文件系统放在中心,不代表客服也要复制同样的工具注册;研究助手的核心不是拥有更多工具,而是让每条结论能回到来源。

    真实工程参考:按问题追踪代码

    q-code 只作为可选的 TypeScript 参照。阅读时不要从入口一路通读,而是带着一个问题走到答案:

    阅读顺序 源码路径 现场要确认的事实
    1. Loop 入口 src/agent/loop.ts 一轮请求如何产生下一轮消息
    2. 工具边界 src/tools/registry.ts 谁把模型意图变成可审计调用
    3. 上下文组装 src/context/prompt-builder.ts 稳定规则和动态事实如何分开
    4. 子 Agent src/agents/registry.ts 分工、生命周期和结果如何回到主流程
    5. 证据链 src/observability/audit.ts 哪些事件能支持重放和定位

    读完这五处,应该能画出一次请求从输入到证据的边界图,而不是记住五个文件名。

    一个失败反例:六个支柱都变成全局变量

    看到一个新框架就重新学习一套名词,最后只记住 API 名称,没有形成判断能力。更糟的实现是:Loop 直接改全局上下文,工具函数自己写日志,Memory 把每句聊天都保存,子 Agent 共享所有权限,界面再从异常文本里猜状态。它们在 happy path 上可以工作,遇到取消、重试或多人并发就互相覆盖。

    修复不需要马上拆成六个包。先选一次真实请求,给每次交接补三个字段:输入来源、允许动作、失败接手者。哪一个字段写不出来,哪一个边界就应该先被澄清。架构图不是终点,能在故障现场指出责任归属才算有用。

    留下一张可复查的地图

    练习:选一个你正在做的 Agent,把它画成六个支柱,但每个支柱只写三行:拥有的状态、允许的副作用、失败时交给谁。再把一个“看起来能工作”的功能换成另一个产品场景,检查图中哪些职责仍然成立、哪些职责必须重新命名。

    完成后保存两份产物:一张六支柱地图,以及一张“模型不能自行决定什么”的清单。以后换模型、换 SDK 或把单 Agent 拆成团队时,先拿这两份东西做差异对照。

    支柱之间会互相放大,也会互相拖累

    六大支柱并不是六项可以独立打分的功能。一个工具系统权限严密,但上下文没有告诉模型哪些路径可读,模型会反复撞墙;Memory 保存得很完整,但 Harness 没有版本和迁移,旧结构一升级就恢复失败;Multi-Agent 并发很多,但 Eval 只看最终文案,重复劳动和错误合并就不会被发现。

    可以把它们看成一条承重链。最弱的部分往往决定用户真正感受到的可靠性。模型升级把任务成功率从 70% 提到 85%,如果写工具仍可越界,产品风险不会因此下降 15%。相反,补上审批、回滚和证据,可能不改变模型基准分,却会显著改变用户敢不敢授权执行。

    下面是一份架构审计切片,它不是配置模板,而是某次代码评审留下的现场记录:

    system: support-agent
    task_sample: "查询退款进度并解释下一步"
    pillars:
      loop:
        observed: "最多 8 步,有 timeout;没有循环检测"
        evidence: "trace/run-184.jsonl"
      tools:
        observed: "订单查询只读;退款工具要求人工确认"
        evidence: "policy/refund-v3.json"
      context:
        observed: "注入订单摘要和当前退款规则版本"
        gap: "没有显示规则生效日期"
      memory:
        observed: "仅保存用户明确确认的联系方式"
      multi_agent:
        observed: "未启用,当前任务无并行收益"
      harness:
        observed: "会话可恢复;外部 CRM 超时会降级"
    decision: "先补规则日期,再扩大灰度"
    

    这份数据最重要的一行是 multi_agent: 未启用。支柱是检查维度,不是功能采购清单。没有并行收益时,不实现多 Agent 反而是成熟选择;关键是团队知道以后在哪些条件下才需要它。

    用一次客服任务观察六次交接

    用户问“上周申请的退款为什么还没到”。Loop 先决定缺少订单号;Context 从当前会话取得已验证的订单引用;Tool System 查询支付平台;返回结果显示银行处理中;Memory 不应把“银行一般三天到账”保存成用户事实;若支付平台和银行状态需要分别查询,Multi-Agent 才可能并行;Harness 负责超时、重试、脱敏日志和页面状态。

    此时如果回答错误,六个支柱提供了不同诊断方向:

    • Loop 是否在证据不足时过早结束。
    • Tool System 是否调用了错误账户或过期接口。
    • Context 是否混入上一笔订单。
    • Memory 是否保存了未经确认的订单号。
    • Multi-Agent 是否把两个不同支付流水合并。
    • Harness 是否在超时后把缓存结果当成实时结果。

    这比一句“模型幻觉了”更有用。幻觉描述现象,支柱地图帮助找到可改变的系统条件。

    三种产品,支柱重心为何不同

    代码 Agent 的副作用集中在文件和 Shell,所以 Tool System、回滚和工作区状态通常最先成为瓶颈。客服 Agent 面对身份、权限与政策时效,Context 和授权证据更重。研究 Agent 可能几乎没有写工具,却需要检索、引用、来源新鲜度和结论不确定性。

    支柱的名字可以不变,验收材料必须跟着领域变化:

    代码 Agent:diff + test exit code + approval receipt
    客服 Agent:identity scope + policy version + action confirmation
    研究 Agent:source URL + retrieved passage + publication date
    

    同样叫 Evidence,三行内容完全不同。若团队拿代码 Agent 的“测试通过”标准去验收研究助手,就会漏掉最重要的引用真实性;拿研究助手的“引用完整”去验收写代码,则无法证明工作区真的可运行。

    Harness 不是最后再包一层壳

    不少项目先完成模型、工具和 Prompt,准备上线时才说“补一个 Harness”。但取消信号、会话编号、日志关联、配置覆盖和恢复协议都会进入核心调用签名,太晚补就要重写大量路径。

    第一天不需要完整 Dashboard,却应该有最小运行信封:runId、sessionId、cwd、abortSignal、eventSink、usageSink。它们不决定模型做什么,只让每次执行可以被定位、停止和计量。这个信封越稳定,未来接 TUI、Web 或后台队列越容易。

    什么时候该升级某个支柱

    升级信号来自重复故障,不来自功能清单。出现以下现场时,才有明确投入方向:

    • Loop 连续调用相同工具且输入不变,需要循环检测或停止策略。
    • 工具拒绝理由散在不同模块,需要统一 Registry 和策略结果。
    • 每轮都全量塞项目文件,需要 Context 预算与 JIT 读取。
    • 用户反复纠正同一长期偏好,才考虑受控 Memory。
    • 独立搜索明显占据串行时间,才考虑只读并行 SubAgent。
    • 故障只能靠重新跑,说明 Harness 的 trace、artifact 或恢复不足。

    这样规划路线,六大支柱就不会变成一张“全部要做”的大饼,而是一套根据现场选择下一项投资的坐标系。

    本文目录
    本文目录