AI notes · Know why / know how

编码 Agent 的本质:一个工具调用循环

编码 agent 没有想象中那么玄。它先让模型读当前上下文;如果模型要调用工具,程序就执行工具,把结果放回上下文;然后再问模型下一步怎么做。模型不再要工具、直接给出回复时,这一轮就结束。

messages = [user_request]

while True:
    response = llm(messages, tools=available_tools)
    messages.append(response)

    if response has no tool_calls:
        return response.final_text

    for call in response.tool_calls:
        # 改文件、跑命令、查外部系统,都发生在工具里
        result = run_tool(call.name, call.args)
        messages.append(tool_result(call.id, result))

这段伪代码不是完整产品,但已经够解释大部分 coding agent。复杂的地方通常不是“有没有循环”,而是循环外面的工程:工具权限、上下文压缩、并发执行、checkpoint、流式事件、用户中断、子 agent、失败恢复,以及怎么把副作用讲清楚。

共同点:模型决定下一步,程序负责真的去做

我更愿意把 coding agent 拆成两层:模型判断下一步该做什么,harness 提供工具、权限、上下文和运行记录。AgentOS、Claude Code、Codex、Hermes 的实现不一样,但这个分工很接近。

  • 消息历史就是工作台。用户请求、模型回复、工具调用和工具结果,最后都会回到同一份上下文里。
  • 工具调用决定是否继续。模型要工具,就执行工具并继续循环;模型不要工具,就进入收尾。
  • 副作用都在工具里。读文件、改文件、跑命令、查外部系统,不是模型直接完成的,是程序按工具协议完成的。
  • 最终回复不等于全部产出。coding agent 的真正产出经常是文件被改了、测试跑过了、报告生成了、外部任务被提交了。

几个实现主要差在循环外面包了什么

系统 循环怎么跑 更值得注意的差异
AgentOS / LangGraph 把模型节点、工具节点、状态和 checkpoint 放进 graph runtime 里。 它更像一台可恢复的状态机。AgentOS 从 LangGraph 拿到 streaming messages / updates,再映射成前端能理解的 run start、tool call、tool result、run finished 等事件。
Claude Code 最小形态就是 Anthropic loop:模型返回 tool_use,程序执行工具,再追加 tool_result Claude Code 的重点不是把 loop 写得多复杂,而是把 harness 做扎实:Bash、文件读写、编辑、权限、skills、压缩、子 agent、后台任务都围着同一个 loop 服务。
Codex 一个 turn 里不断发起 sampling request,处理 streaming ResponseItem,遇到工具输出就继续下一次采样。 Codex 的循环更事件化:边接收模型流式输出,边启动工具 future,把工具结果写回 history;还要处理用户中途输入、自动压缩、上下文窗口切换,以及 end_turn=false 这种继续信号。
Hermes AIAgent.run_conversation() 在 provider 调用和工具执行之间切换,直到模型给出普通文本。 Hermes 更强调多入口和多 provider。它把不同 provider 的消息格式收敛到内部格式,工具可以顺序或并发执行,session、memory、审批、delegation 都接在同一条循环上。

为什么这个理解有用

先按这个 loop 看,很多问题会变得更直观。agent 反复改同一个文件,可能是工具结果没有让它确认任务完成,也可能是上下文里缺少明确的停止信号。工具权限之所以重要,也是因为真正的副作用发生在工具里;模型只是提出调用请求。

所以,一个好 agent 产品不只是 prompt。Prompt 只是循环里的一部分。真正拉开差距的是运行环境:工具是否可靠,结果是否可追踪,失败后能不能恢复,危险动作要不要审批,长任务怎么压缩上下文,用户能不能看清楚系统到底做了什么。

自己做 agent,可以先守住这几件事

  1. 先把最小 loop 跑通。不要一上来就做多 agent、记忆、插件市场。先证明“模型要工具 → 执行工具 → 回填结果 → 继续”这条链路稳定。
  2. 工具结果要给人和模型都看得懂。模型靠它判断下一步,人靠它排查问题。
  3. 副作用要有边界。文件写入、shell、网络、审批、敏感数据,都应该在工具层有清楚规则。
  4. 结束条件要对任务负责。“没有 tool call”只是协议上的结束。产品上还要确认任务是否真的完成:测试是否通过,文件是否存在,外部任务是否成功。

这篇只讲 loop,不展开所有周边机制

我这里用 AgentOS / LangGraph、Claude Code、Codex 和 Hermes 做参照,是因为它们都能看到同一个骨架:模型给出下一步,工具产生副作用,工具结果回到上下文。插件、MCP、权限系统、子 agent 协调都很重要,但它们是下一层问题。先把这个循环看懂,再看那些机制会轻松很多。