乐于分享
好东西不私藏

agent loop 不是黑盒:四家源码摊开给你看

agent loop 不是黑盒:四家源码摊开给你看
写在前面的坐标系。后面的连载一~四会讲技术细节,这一篇先回答一个问题:业内主流 agent 框架在 loop 这件事上,各自押注了什么?

一句话开场

LLM 这两年学会了两件事:第一年学会"调工具",第二年学会"在循环里不死"。

今天要聊的,就是第二件事。

在 AI 编程助手这个赛道上,已经有四个工业级方案跑出来:OpenAI 的 Codex、Anthropic 的 Claude Code、Nous Research 的 Hermes-Agent、LangChain 的 LangGraph。它们每一家都把"agent loop"这个本来 5 行就能写完的东西,做成了 1000 到 4000 行的庞然大物。

为什么长成这样?因为生产环境会让朴素 loop 在 11 个地方坏掉。 每坏一次,loop 就长大一段。看似简单的 while 循环,真要扛住的生产,必然要涨点代码量。

这一篇不打算直接讲技术细节,先把四家的设计哲学和取舍摊开,给你一个坐标系。后面四篇连载,所有技术内容都建立在这个坐标系上。读懂这一篇,后面读起来会顺很多。


一、先看脸:四家方案的体量对比

方案
仓库
核心语言
核心 loop 文件
行数级
OpenAI Codex CLI
github.com/openai/codex
Rust
codex-rs/core/src/codex_thread.rs
几千行 + 模块化
Anthropic Claude Code
npm 闭源,被 source map 还原
TypeScript (Bun)
query.ts
1400+ 行单文件
Nous Research Hermes-Agent
github.com/NousResearch/hermes-agent
Python
agent/conversation_loop.py
 (run_conversation)
约 3900 行
LangGraph
github.com/langchain-ai/langgraph
Python
libs/langgraph/langgraph/graph/state.py
图执行引擎

这四个数字本身就是故事:同一个问题,Anthropic 用 1400 行一个文件搞定,Hermes 用了 3900 行拆出十几个文件,OpenAI 用 Rust 的强类型把状态机做厚,LangGraph 直接换范式做"图的框架"。


二、四个核心问题的不同答案

为了让你带着"为什么"读后面的连载,这里把 4 个最关键的工程问题拎出来对比,每家怎么答。

问题 1:loop 长什么样?

答案 — 任何教程第一节课:

 while True:     response = call_llm(messages)     if response.has_tool_calls():         result = execute_tools(response.tool_calls)         messages.append(response,result)     else:         break

四家都从这里出发,但走了四条完全不同的路:

  • Claude Code
    :单文件 while(true) + async generator,1400 行所有逻辑塞一个文件。简单、确定、可读。
  • Codex
    :Rust async (tokio::sync::Mutex),CodexThread 是核心结构体,Arc 共享状态。线程安全、零成本抽象。
  • Hermes-Agent
    :Python 同步 + threading.Lock(用于预算计数),3900 行单函数 run_conversationIterationBudget 父 90 / 子 50。
  • LangGraph
    :不是 loop,是构造 loop 的框架。你定义节点和边,框架帮你跑。

对比的关键洞察:前三家是"loop 的不同实现",LangGraph 是"loop 的元框架"。它不替你做 loop,它让你画 loop。

问题 2:工具可以并发吗?

这是个分水岭。

Claude Code 选了单线程。一次只跑一个工具,完事再跑下一个。Anthropic 的官方说法:工具是状态机的副作用,单线程才不会有两个工具同时写同一个文件这种竞态。代价:bash 卡死会冻住整个 loop。

Hermes-Agent 在我之前写的素材里被描述为"多线程并发工具",但我直接读了 agent/conversation_loop.py 和 iteration_budget.py 之后,这个说法要修正 — Hermes 的多线程 (threading.Lock) 是用在 IterationBudget 计数器上,不是并发执行工具调用。它本质和 Claude Code 一样:一次一个工具,串行执行。

Codex 用 Rust 的 tokio,从架构上支持异步并发,但具体是不是并发调工具要看上层实现。这个我有把握的程度比 Hermes 弱,文章里我会按"支持但默认偏保守"写。

LangGraph 通过 Send 节点和 fan-out 边显式支持并行。用户画图时决定哪些节点并行,框架负责调度。

对比表:

方案
工具并发
理由
Claude Code
确定性 > 吞吐
Hermes-Agent
threading 只用于预算计数
Codex
看实现
架构支持,默认偏保守
LangGraph
显式开启
用户画图时决定

问题 3:上下文快满了怎么办?

这是 loop 设计最见功夫的地方。

Claude Code(internals.laxmena.com/p/why-claude-codes-agent-loop-is-over,2026-06-03 还原):两层压缩。

  • 主动 (proactive)
    :4 级,从便宜到贵,Tool Result Budget → Snip → Microcompact → Autocompact
  • 被动 (reactive)
    :API 返 413 才触发,断路器保证只触发一次

Hermes-Agent(context_compressor.py + context_engine.py):

  • protect_first_n=3
    (前 3 条非系统消息原样保留)
  • protect_last_n=6
    (尾部 6 条原样保留)
  • threshold_percent=0.75
    (75% 触发压缩)
  • 辅助模型(auxiliary client)调轻量 LLM 总结
  • 可插拔的 ContextEngine 接口
     — 第三方可以用 LCM、DAG 等方式替换

Codex(codex-rs/core/src/compact.rs + compact_remote_v2.rs):

  • 支持远程压缩
    (should_use_remote_compact_task + compact_remote_v2.rs)— 把压缩扔到远端模型跑
  • 有 hook 系统:run_pre_compact_hooks / run_post_compact_hooks
  • 区分 inline 和 remote 两种压缩路径
  • 还支持多 agent 模式下的压缩协调

LangGraph:不做自动压缩。它是图框架,自己不管上下文,上下文管理交给上层的 LangChain 组件。但有 Checkpointer 机制做状态持久化。

对比表:

方案
压缩策略
关键特征
Claude Code
两层 (proactive + reactive)
4 级递进,断路器
Hermes-Agent
单层 + 辅助模型
protect_first/last_n,可插拔引擎
Codex
远程 + hook
支持远端压缩,有 pre/post hook
LangGraph
不做
框架层只管图执行,不管上下文

问题 4:loop 怎么"换挡"到不同任务?

这是最深的工程问题,放在第四节"递归与层级"会展开。前论先埋个雷:

  • Claude Code
    :不用递归,用状态机。早期版本递归调用自己,长会话爆栈。现在用 State 对象传状态,continue 就是状态转换。子 agent 通过 Task 工具启动,父 loop 只拿摘要
  • Hermes-Agent
    :父子 agent 双层结构IterationBudget 父 90 / 子 50,子 agent 有独立上下文,总迭代可以超父 cap
  • Codex
    :显式 MultiAgentMode + MultiAgentVersion。从协议层就支持多 agent,有 parent_thread_id / forked_from_thread_id 这些字段。
  • LangGraph
    :subgraph 原生支持interrupt 显式暂停,Command(resume=value) 显式继续。

三、四家方案的"哲学"

如果你只想记一句话带走,这就是:

  • Claude Code
     押注单线程确定性。一个文件、一种范式、一种选择,把所有复杂度摊在 loop 里。适合"我要的是稳,不是快"。
  • Hermes-Agent
     押注辅助模型 + 可插拔。压缩交给轻量模型,引擎接口开放,plugin 生态扩展。适合"我要的是灵活,不是死磕一个方案"。
  • OpenAI Codex
     押注远程 + 协议化。压缩可以扔远端,多 agent 是协议层一等公民,h有完整的 hook/approval 体系。适合"我要的是企业级,不是 prototype"。
  • LangGraph
     押注图范式。loop 不是写出来的,是画出来的。适合"我要的是控制流,不是黑盒 loop"。

这四家没有对错,只是取舍。 你写的 vibe coding 工具,选错范式可能比选错模型还致命。


四、这个连载会怎么展开

前论(本篇):四家框架横评 ← 你现在读的位置 连载一:搭一个 agent loop - 从朴素到生产级 连载二:失败模式 - loop 在哪里坏,怎么不坏 连载三:记忆与压缩 - 上下文快满的工程解法 连载四:递归与层级 - 父 agent 怎么看见子 agent

每篇 1500-2000 字,代码示例全部用伪代码,事实点全部基于开源仓库源码、官方文档、internals.laxmena.com 还原分析。

读完前论你已经知道"业内在用什么、为什么"。后面四篇,我们钻进去看"具体怎么搭"。


资料来源

  • OpenAI Codex: github.com/openai/codex codex-rs/core/src/codex_thread.rs,compact.rs
  • Claude Code: internals.laxmena.com/p/why-claude-codes-agent-loop-is-over (v2.1.88 还原)
  • Hermes-Agent: github.com/NousResearch/hermes-agent agent/conversation_loop.py,context_compressor.py,context_engine.py,iteration_budget.py
  • LangGraph: github.com/langchain-ai/langgraph libs/langgraph/langgraph/graph/state.py,types.py
  • AutoGen: github.com/microsoft/autogen README (维护模式说明)