本文把 Agent 的演化拆成一条工程主线:从单轮问答,到上下文装配,到 ReAct 循环,到结构化工具调用,到分层记忆,再到完整的 Harness。最后结合 Pi、OpenCode、Codex、Hermes 四类路线,给出一套可落地的参考架构和生产检查清单。

很多团队第一次做 Agent,都会从一个朴素念头开始:既然大模型已经能读懂需求、生成代码、解释报错,那是不是把用户输入塞进去,再把它吐出来的命令执行掉,一个智能助理就做好了?

真正做进去之后才会发现,问题不在模型会不会回答,而在模型每一次回答之后,系统还能不能继续。

一个 Agent 进入真实业务,至少要面对七件事:上下文怎么装,循环怎么停,工具怎么调,历史怎么存,权限怎么拦,状态怎么恢复,多个 Agent 怎么并行。模型像发动机,负责产生下一步动作;Harness 像底盘、传动、刹车和仪表,负责让这个动作稳定发生在正确的地方。

本文把 Agent 的演化拆成一条工程主线:从单轮问答,到上下文装配,到 ReAct 循环,到结构化工具调用,到分层记忆,再到完整的 Harness。最后结合 Pi、OpenCode、Codex、Hermes 四类路线,给出一套可落地的参考架构和生产检查清单。

一、起点不是 Agent,而是一个只负责 predict next token 的函数

最早期的大模型应用,本质上是这样一个接口:

answer = LLM(question)

模型参数里装着训练得来的世界知识,但训练不会自动带来会话记忆。用户上一轮说过名字,这一轮系统必须重新提交;用户偏好、任务状态、当前目录、可用命令,也都必须由应用在每次调用前重新组织。

这带来第一个关键认知:模型看见的一切,都是运行时在调用前装配出来的。

所以 Q&A Bot 的第一项工程进步,不是换更聪明的模型,而是出现上下文装配层。它把系统指令、角色约束、用户输入、近期历史拼成一次请求。看起来只是字符串拼接,实际上已经埋下后来所有 Agent Harness 的核心原则:上下文不是聊天记录的自然堆叠,而是一份被运行时筛选、排序、裁剪后的工作集。

落地时建议把上下文装配拆成三类输入:

  • 系统契约:身份、边界、输出格式、不可触碰的红线。
  • 本轮任务:用户目标、约束、验收标准。
  • 可裁剪历史:只保留与当前决策相关的消息、工具结果和文件状态。

这里最常见的错误,是把全部历史原样塞回模型。短期看省事,长期会带来三件后果:成本上升,关键信号被噪声淹没,模型更容易被过期信息带偏。上下文装配的目标不是“多给信息”,而是“给对信息”。

二、Agent 的分水岭,是模型到环境再到模型的闭环

单轮 Bot 只需要回答一次,Agent 则必须根据行动结果继续决策。ReAct 的价值在于,它把推理轨迹和外部动作交错起来:模型形成意图,系统执行动作,环境返回观察,观察再进入下一轮推理。

真正的工程闭环可以写成:

while not finished:
    response = model(context)
    if response.has_action:
        observation = environment.execute(response.action)
        context.append(response.action, observation)
    else:
        return response.answer

这个 while 循环,就是最早的 Agent Runtime。模型仍然只生成 token,真正负责继续运行的是模型外面的程序。程序要解析输出,判断是否结束,调用环境,把结果写回上下文,还要处理超时、重试、异常和终止条件。

很多 Demo 会死在循环边界上。常见坑包括:没有最大轮次,模型陷入工具空转;没有停止条件,任务完成后继续自我发挥;没有观测回写,模型不知道刚才的命令成功还是失败;没有失败分支,一次网络错误就让整个任务卡死。

生产里要把 Agent Loop 当成状态机,而不是一段 prompt 加几个 if。至少要有四类状态:等待模型决策,等待工具执行,等待用户审批,已经结束。每一次状态迁移都要留下事件,后续才能恢复、审计和回放。

三、工具调用要结构化,不要让模型“像命令一样说话”

早期 Agent 常让模型输出Search[Wikipedia]这类文本,再由程序用正则解析。灵活,但脆弱。格式会漂移,参数会缺失,解释文字会混进命令,多轮之后几乎不可维护。

结构化 Tool Calling 改变了这件事。工具通过 schema 注册,模型输出带工具名、调用 ID 和参数的对象;运行时负责校验、路由、执行、回写结果。这里的关键不是“模型会调用工具”,而是工具调用成为可验证、可路由、可审计的协议。

一个生产级工具层至少要有五件事:

  • Schema:名称、用途、参数类型、必填项、约束条件。
  • Router:按名称找到实现,拒绝未知工具,校验参数。
  • Context ID:调用 ID 与结果 ID 对齐,避免 observation 错配。
  • Guardrail:超时、并发限制、敏感参数脱敏、危险动作二次确认。
  • Audit:谁发起、何时执行、改了什么、结果如何、是否回滚。

尤其要注意副作用工具。读文件和搜索可以宽松,写文件、执行命令、访问网络、操作数据库必须默认收紧。Q&A Bot 的错误停在屏幕上,Coding Agent 的错误会变成被覆盖的文件、误删的数据和越权访问。

四、记忆系统最难的不是存储,而是写入和读取策略

Agent Loop 解决连续行动,却没有解决跨会话积累。完整历史会越来越长,上下文窗口始终有限,于是系统必须把过去拆成两个空间:本轮模型可见的 Working Memory,和模型外部可持久化、可检索的长期记忆。

长期记忆可以粗分为三类:

  • 程序记忆:技能、流程、约定,比如 SKILL.md、团队规范、常用脚本。
  • 语义记忆:稳定事实、项目知识、用户偏好、接口约定。
  • 情景记忆:某次任务发生了什么,执行了哪些动作,结果如何。

真正困难的不是把这些内容放进数据库,而是决定什么值得保存。噪声写入会污染检索,冲突事实会让模型摇摆,过期偏好会让系统越学越错。因此记忆系统很快会长出提炼、合并、门控和反思流程。

落地建议:

  • 写入前做价值判断:是否影响后续任务,是否重复,是否稳定,是否可被验证。
  • 写入后做冲突处理:新事实覆盖旧事实,旧事实保留版本,无法确认时标记待确认。
  • 读取前做预算控制:检索几条,每条多长,是否挤占当前任务上下文。
  • 定期做遗忘和纠错:低价值记忆降权,错误记忆撤回,长期未使用信息归档。

记忆不是外挂一个向量库就结束。向量库只解决相似度检索,不解决事实是否可信、是否该进入当前上下文、是否会和系统指令打架。

五、什么时候说明你需要独立 Harness,而不是更大的 prompt

当能力变多以后,Agent Loop 外围会同时出现一批工程问题。只要这些信号出现两个以上,就说明你需要把 Harness 当成独立架构来设计。

  • 会话要恢复:进程崩溃、用户退出、机器重启后,任务还能不能从一致状态继续。
  • 副作用真实:命令、写文件、网络访问不能依赖模型自觉。
  • 上下文要压缩:长任务要保留关键事实,同时释放上下文窗口。
  • 客户端变多:TUI、Web、IDE、桌面端、SDK 要看见同一个运行状态。
  • 扩展要装配:工具、MCP、Skills、Hooks、配置需要确定性的发现和加载机制。
  • 任务要并行:子 Agent 要有独立上下文、权限、历史和生命周期。

可以把边界这样划分:Agent 决定下一步做什么,Harness 决定这一步在什么上下文、什么权限、什么生命周期、什么持久化规则下发生。

这也是今天 Coding Agent 看起来像小型操作系统的原因。不是谁一开始就想造操作系统,而是模型每撞上一次真实边界,工程系统就被迫补上一层:记不住就装配上下文,碰不到世界就接工具,一步做不完就启动循环,历史装不下就分长期记忆,副作用变强就加权限和沙箱,一个循环不够就派生子 Agent。

六、四条路线的取舍:没有标准答案,只有环境适配

1. Pi:把最小 Harness 做紧,用成本换效率

Pi 的意义在于证明一件事:同一个模型,换一套 Harness,结果可能差很多。文中引用的公开基准里,Pi 在 Composio 的 30 个 Agentic Tasks 中,用 DeepSeek V4 Flash 取得较高通过率和很低中位成本;Databricks 的代码任务基准也显示,Pi 的多组配置靠近 Pareto 前沿,部分同模型组合切换到 Pi 后质量基本不变,成本却能明显更低。

它的方法很克制:默认只暴露 read、write、edit、bash 四个工具,Resource Loader 显式装配 SYSTEM.md、AGENTS.md、Skills、Prompt Templates,Session Manager 通过活动分支和 Compaction 把完整会话投影成更紧的 Working Memory。结果是每轮携带上下文更少,工具描述更少,历史噪声更少,模型用更少轮次抵达结果。

但小也有代价。Pi 当前不内置强权限系统,默认继承启动用户权限。放进高风险环境,需要外置容器、只读挂载、网络隔离和凭证管控。Pi 适合轻量任务、内部工具和成本敏感场景,不适合直接暴露给不可信用户或生产数据库。

2. OpenCode:用事件和 Profile 组织身份、历史和多客户端

OpenCode 的核心不是多界面,而是结构化状态。它把一次 Assistant Message 拆成 reasoning、text、tool call、tool result、step start、step finish、patch、compaction 等 part。模型想了什么,工具何时开始,补丁改了哪些文件,上下文何时压缩,都成为有结构、有生命周期的数据。

Agent Profile 在这里很关键。它不是换皮 Prompt,而是把名称、描述、Prompt、模型、Mode、Permission、生成参数、最大步数放进同一个配置对象。Build、Plan 是主 Agent,General、Explore 是子 Agent,Compaction、Title、Summary 是隐藏后台 Agent。同一个 Agent Loop 装载不同身份,每个身份拥有不同工具边界。

这套设计换来四个能力:Session 可恢复,行为可审计,子 Agent 可隔离,同一运行时可被 TUI、Web、桌面端、SDK 同时消费。代价也很直接:配置合并、权限组合、事件顺序、数据库投影、压缩边界都会变复杂,后台 Compaction、Title、Summary 还会引入额外模型调用。

如果你的场景是团队协作、多入口接入、需要回看过程,而不是只关心一次短任务成败,OpenCode 的事件驱动思路很值得借。

3. Codex:把任务生命周期和安全边界做成控制平面

Codex 回答的是另一个问题:怎样让一个并不完全可靠的模型,安全、连续、可恢复地操作真实计算机。

它的协议骨架是 Thread、Turn、Item。Thread 承载一个可持续多轮的任务,Turn 表示用户推动任务前进的一次过程,Item 把模型消息、推理、命令执行、文件修改、工具调用和审批拆成可观察单元。任务可以 Start、Resume、Fork、Interrupt,运行中的 Turn 还可以 Steer。保存的不是聊天记录,而是一棵能继续生长的任务状态。

Thread Manager 是控制平面。它维护活跃任务表,把协议请求、运行实例和持久化历史接在一起。任务还在内存就直接投递,任务离开内存再从 Thread Store 或 Rollout 装回历史,重建可运行线程。

安全上,Codex 有双层边界:Approval Policy 决定某个动作是否必须询问用户,Sandbox Policy 决定即便用户允许,命令仍然能写哪里、能否联网、能碰哪些系统资源。用户点一次同意,不等于模型拿到整台电脑;这条边界必须由执行路径保证,而不是由模型承诺谨慎。

代价也明显。文中引用的 OpenBench 小样本对比里,同一个模型放进多套 Harness,Codex 通过率并非最高,耗时和 token 消耗都更重。它选择的不是最轻路径,而是让长任务可以被监督、中断、恢复和并行管理的路径。强合规、真实执行环境、多客户端、多后台 Agent 的场景,更适合这套思路。

4. Hermes:把注意力延伸到下一次任务

如果说 Pi 强调最小闭环,OpenCode 强调事件化状态,Codex 强调安全控制平面,Hermes 更强调经验沉淀。它关心一个长任务结束后,系统能不能把可复用技能、稳定偏好和踩坑记录整理成下一次任务可利用的资产。

这条路线提醒团队:不要把记忆只做成“检索旧聊天”。真正有价值的是跨任务学习:哪些命令组合有效,哪些目录结构容易误判,某类需求应该拆成哪几步,哪些错误模式反复出现。长期看,这会决定系统越用越聪明,还是越用越乱。

七、可落地的参考架构

如果把上面所有能力收进一张图,可以按九层搭建。

  • 接入层

TUI、Web、IDE、SDK、定时任务统一进入 API。接入层不直接碰模型,只提交任务和接收事件。

  • 会话与线程控制平面

用 Thread 或 Session 表示长期任务,用 Turn 表示一次推进,用 Item 表示可观察单元。支持 Resume、Fork、Interrupt、Steer、子线程派生。

  • 上下文装配器

装配系统契约、本轮任务、近期历史、技能、检索结果、压缩摘要。必须有 token 预算和裁剪策略。

  • Agent Loop

显式状态机,包含最大轮次、停止条件、重试策略、异常恢复、用户审批节点。

  • 工具路由器

统一注册内建工具、插件工具、MCP 工具。所有调用带 ID,所有结果可审计,危险动作可 dry run。

  • 执行沙箱与权限

文件系统、进程、网络、凭证分域管控。默认拒绝,按工具白名单放行,高风险动作强制确认。

  • 事件与轨迹存储

全量事件用于回放,摘要事件用于查询,Rollout 或 JSONL 用于恢复,SQLite 或元数据库用于索引。

  • 记忆管线

会话结束或任务阶段结束时,后台流程提炼事实、合并冲突、更新技能、生成经验摘要。读取时受预算和置信度约束。

  • 观测与评测

记录通过率、轮次、成本、时延、工具失败率、回滚率、人工接管率。每次模型或 Prompt 变更都跑回归集。

最小可行版本不需要九层全建。第一版可以只做四件事:显式 Loop、结构化工具、Session 事件、危险动作审批。先把边界立住,再逐步加记忆、压缩、沙箱和子 Agent。

八、从 Demo 到生产的十项检查清单

  • 崩溃后可恢复:杀掉进程,重新打开,任务能从一致状态继续。
  • 危险动作可确认:写文件、执行命令、联网、删数据有明确审批点。
  • 副作用可回滚:补丁可撤销,命令有日志,数据库操作有事务或补偿。
  • 上下文有预算:每轮进入模型的 token 有上限,超限必须裁剪而非硬塞。
  • 历史可压缩:长会话能把早期历史变成摘要,同时保留近期关键消息。
  • 工具调用可追踪:调用 ID、参数、结果、耗时、错误原因全部可查。
  • 子 Agent 可隔离:独立上下文、独立权限、独立历史,不共享主循环状态。
  • 记忆可纠错:错误事实可撤回,冲突事实有版本,低价值信息会遗忘。
  • 成本有护栏:单任务轮次、token、工具调用次数、人工接管次数都有阈值。
  • 变更有回归:换模型、改 Prompt、加工具、调权限,都必须重跑评测集。

这套清单比“选哪个模型”更重要。模型能力越强,外层运行时越不能含糊;否则能力每提高一分,风险也会放大一分。

九、怎么选路线

如果是内部脚本、个人助理、成本敏感的小工具,优先借鉴 Pi:小内核、少工具、紧上下文、快循环。先把权限外置,再谈扩展。

如果是团队 Coding Agent、多客户端、需要过程回放和审计,优先借鉴 OpenCode:Profile 表达身份,Event 表达过程,SQLite 投影支撑查询和恢复。

如果 Agent 要操作真实计算机、连接生产环境、面对强合规要求,优先借鉴 Codex:Thread 控制平面,Approval 和 Sandbox 双层边界,Rollout 支持恢复,子线程支持并行。

如果业务强调长期改进,希望系统越用越顺手,优先补 Hermes 式经验沉淀:任务结束后做整合,把一次性结果变成可复用技能,把反复踩坑变成流程约束。

十、结语

Agent 看起来越来越像小型操作系统,并不是因为谁一开始就规划了操作系统。每一层都是模型撞上边界以后,工程系统不得不补上的回答。

记不住,就装配上下文;碰不到世界,就接入工具;一步做不完,就启动循环;历史装不下,就分出长期记忆;副作用变强,就长出会话、权限、沙箱、事件和子 Agent。

模型还会继续变强,但 Harness 不会因此消失。未来的分水岭,未必只是谁的模型更聪明,而是谁能为同一个模型搭出更好的上下文、更稳的循环、更清晰的边界,以及一套不会在长期使用中越学越乱的记忆。

Agent 负责决定下一步,Harness 负责让这一步持续、可控、可恢复地发生。真正拉开差距的,往往不是那一行模型调用,而是调用之外的一整套承载系统。

资料展示

下面是我整理的AI大模型学习资料和工具包预览,适合收藏后按主题逐步学习。

AI大模型资料展示 1

AI大模型资料展示 2

AI大模型资料展示 3

AI大模型资料展示 4

AI大模型资料展示 5

如果你想看完整资料目录,可以在评论区留言「资料」;也欢迎告诉我你更关注AI大模型里的哪类内容。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐