为什么 Claude Code、Codex CLI、OpenCode 都不用 LangChain?——揭秘头部编码智能体的真实架构

当所有人都在讨论”用哪个 Agent 框架”时,真正站在潮头的编码智能体产品,几乎清一色选择了裸写循环。这不是巧合,而是一场值得深挖的架构哲学分歧。

一、一个反直觉的事实

如果你在 2025 年之后接触过 AI 编程工具,大概率听说过这几个名字:Claude Code(Anthropic 官方 CLI)、Codex CLI(OpenAI 官方 CLI)、OpenCode(开源新秀)。它们是目前最炙手可热的一批编码智能体(Coding Agent)。

一个很容易想到的问题是:这些产品是用什么框架搭建的?LangChain?LangGraph?CrewAI?

答案出人意料——一个都没用。它们全部是基于模型厂商原生 API 自研的 Agent 循环。而且不只这三家:Aider、Cline、Gemini CLI、Goose、Pi……你能叫得上名字的主流编码智能体,几乎清一色走上了”无框架、裸写循环”的路线。

为什么?这篇文章试着把这件事讲透。

二、先破除一个误解:Agent 到底是什么

在讨论框架之前,先对齐一个认知。很多人被复杂的框架术语(Agent 类、Executor、Graph Node、State Machine)熏陶久了,以为智能体是一个”很重的架构问题”。

但 Claude Code 的源码会告诉你一个朴素得近乎扎心的真相:

Agent = 系统提示词 + 一个 while 循环 + 工具调用 + 退出条件

就这么多。所谓”智能”,全部来自模型本身;所谓”Agent 工程”,其实是围绕这个循环搭建的运营设施。

三、三巨头架构解剖

先上一张总览表,再逐个拆解:

工具 用框架吗 技术栈 核心循环形态
Claude Code 否 TypeScript + React/Ink(终端 UI),直连 Anthropic Messages API 一个 while(true) 异步生成器
Codex CLI 否 早期 React/TypeScript/Node,2025 年中重写为 Rust,直连 OpenAI Responses API 同样的朴素循环
OpenCode 否(不用 LangChain) Go 服务端 + TypeScript 客户端,模型层用 Vercel AI SDK 做多厂商抽象 客户端/服务端架构,server 跑循环

3.1 Claude Code:一个循环统治所有形态

对 Claude Code 的源码分析显示,它的核心是 query.ts 里的一个 while(true) 异步生成器:

1
2
3
4
5
6
7
8
9
10
11
12
13
组装上下文(系统提示 + 历史 + CLAUDE.md)
↓
调用 Claude API(携带工具定义)
↓
解析响应中的 tool_use 块
↓
权限校验(deny > ask > allow 三级)
↓
执行工具
↓
结果回填到历史
↓
回到循环开头,直到模型输出纯文本为止

整个代码库没有 agent 类,没有状态机,没有图编排。CLI 版、SDK 版、IDE 插件版、headless 版,全部收敛到同一个 queryLoop() 上。

更有意思的一个数据:社区逆向分析估算,Claude Code 代码库中真正的”AI 决策逻辑”只占约 1.6%,剩下 98% 是权限系统、上下文压缩、会话持久化、Hook 机制等工程设施。Anthropic 甚至透露,Claude Code 约 90–100% 的代码由 Claude 自己写成。作者把这种哲学概括为——“最小脚手架,最大运营框架”。

3.2 Codex CLI:从 Node 到 Rust 的重写

OpenAI 的 Codex CLI 早期是 React + TypeScript + Node 的组合,2025 年年中用 Rust 完全重写(保留了少量 TS)。它的循环和 Claude Code 在结构上几乎一模一样:读取任务 → 调模型 → 执行 shell/文件工具 → 结果回填 → 循环。

差异只在协议层:它对接的是 OpenAI 的 Responses API 和 function calling,而不是 Anthropic 的 tool use 协议。重写为 Rust 的动机也直白——终端工具对首字延迟(TTFT)极度敏感,任何一层的运行时开销都要抠掉。

3.3 OpenCode:唯一”用了库”的,但那不是 Agent 框架

OpenCode 是三者中最接近”用了框架”的,但严格说它用的是 Vercel AI SDK——一个多模型统一调用库(屏蔽 Anthropic/OpenAI/DeepSeek 等不同厂商的协议差异),而不是 LangChain 这种 Agent 编排框架。

它的架构也最有意思:

  • Go 服务端:跑 agent 循环、工具执行、MCP 集成、SQLite 会话存储;
  • TypeScript 客户端:TUI(1.0 版渲染层甚至用 Zig 自研)、桌面端、Web 端、IDE 插件,全部连接同一个 server;
  • 模型层通过 Vercel AI SDK 支持任意厂商。

所以准确的说法是:OpenCode 用了模型调用抽象库,但 Agent 编排层面依然是自研循环。这两者的区别,正是本文想讲清楚的核心。

四、那个循环长什么样

把三家的实现抽象成伪代码,本质上是同一段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
while True:
# 1. 组装上下文:系统提示 + 对话历史 + 项目规则文件
context = build_context(
system_prompt,
history,
project_rules, # CLAUDE.md / AGENTS.md
)
# 2. 调用模型,传入工具定义
response = model_api(
context,
tools=[read, write, edit, bash, grep, ...],
stream=True,
)
# 3. 判断模型想干什么
if response.has_tool_calls:
for call in response.tool_calls:
# 4. 权限校验——这是安全的关键闸门
if permission_system.allows(call):
result = execute_tool(call)
else:
result = ask_user_or_deny(call)
history.append(result)
continue # 带着工具结果,回到循环开头
else:
# 5. 模型输出纯文本 = 任务完成,退出
break

就这二十行。你会问:就这?那些”多轮规划””反思””ReAct 推理链”呢?

答案是:全在系统提示词里,由模型自己完成。现代模型(Claude 4.x、GPT-5 系列、DeepSeek-V3 等)的能力已经强到——你只需要在 prompt 里告诉它”你应该先读文件再修改,修改前先搜索确认”,它就会在循环中自发地展现这些行为模式。**规划、反思、纠错,从”框架代码”迁移到了”提示词”里。**这正是范式转移的分水岭。

五、为什么头部产品集体绕开框架?

这不是跟风,而是几条非常具体的工程权衡。

5.1 上下文和 token 的完全控制权

编码智能体的命脉是上下文窗口管理。Claude Code 面对约 200K token 的窗口,每次模型调用前要执行多级压缩策略(截断工具输出、摘要历史、丢弃低价值信息)。OpenCode 则用一个隐藏的 system agent 做上下文摘要压缩。

这套精细的、逐 token 的操作,在框架的抽象层之下很难精确控制。而当你遇到 prompt cache 命中率莫名下降、模型行为诡异、上下文超限这些问题时,“我到底发了什么给模型”是唯一能救你的信息。框架恰恰最容易把这层透明度遮掉。

顺带一提,这也是个与缓存强相关的细节:上下文压缩如果插在对话中间,会打断前缀缓存——OpenCode 就因此被社区批评过。只有自己写循环,才能把”压缩策略”和”缓存命中”当成一个整体来优化。

5.2 延迟是终端产品的生死线

CLI 工具的用户盯着终端等第一个字出现。TTFT(首字延迟)每多 100ms 都可感知,而任何框架层的中间抽象、序列化、图调度、状态管理,都是叠加在 TTFT 上的税。Codex CLI 干脆用 Rust 重写来抠开销,就是这个逻辑的极致体现。

5.3 框架本身的演进风险

LangChain 长期被诟病的问题很具体:

  • 抽象层过厚:几层封装之后,你不知道最终发给模型的 prompt 是什么样;
  • 破坏性变更频繁:版本迭代快,生产环境升级像拆盲盒;
  • 失败难以排查:中间层一多,报错栈就变得不可读。

一些公司(如 Octomond)公开分享了从生产环境移除 LangChain 的经历,理由正是上面这几条。对一个要维护数年的产品来说,几千行自己完全能看懂的循环代码,比一层随时会变的第三方依赖更可控。

5.4 与模型原生能力对齐的速度

模型厂商的 tool use 协议、流式输出、prompt caching 机制更新极快。直接对接原生 API 的产品,可以第一时间吃上新能力;而框架要先把新特性抽象进自己的层,中间永远隔着一段延迟。对于 Anthropic 和 OpenAI 自己的官方工具来说,更是”自家 API 自家先用”,绕过任何中间层都是自然选择。

六、那框架什么时候仍然有价值?

必须公平地说:“头部编码智能体不用框架” ≠ “框架没用”。

框架真正发光的场景,和编码智能体恰好错开:

场景 更合适的工具 原因
多智能体协作、显式状态图编排 LangGraph 图执行模型、断点恢复、人工审批节点,比手写循环省力得多
角色分工明确的多 agent 团队 CrewAI 声明式角色定义,快速搭建
文档管道(RAG 检索/切块/重排) Haystack 这类”数据处理流水线”正是它的强项
单人编码、单一模型、终端交互 裸写循环 控制力最强、延迟最低、最好排查

一个简单的判断方法:你的产品里,”编排复杂度”和”模型单次调用能力”哪个是主要矛盾?

  • 编排复杂(多角色、多阶段、需人工介入)→ 框架帮你省下大量胶水代码;
  • 模型能力是主要矛盾(单次调用的质量决定成败)→ 框架帮不上忙,甚至碍事,裸写循环 + 精心打磨 prompt 和上下文才是正解。

编码智能体恰好是后者的典型:一个强模型 + 一把好工具 + 一个循环,就够了。

七、真正的竞争在循环之外

回看 Claude Code 那 1.6% vs 98% 的数据,你会发现这些产品的护城河根本不在”Agent 架构”上,而在循环之外的运营设施:

  • 权限与安全系统:三级权限校验、沙箱执行、危险命令拦截——用户敢把 rm -rf 交给它执行,靠的是这一层;
  • 上下文管理:多级压缩、项目规则注入(CLAUDE.md/AGENTS.md)、工具输出的智能截断;
  • 会话持久化:中断恢复、跨天继续;
  • 可扩展性:MCP 协议接入外部工具、Hook 机制、SDK 化(Claude Code 可以作为库被嵌入)。

这些是 LangChain 不提供、也不打算提供的东西。框架解决的是”怎么把模型串起来”,而头部产品在解决”串起来之后怎么可靠地跑在生产环境里”——后者的答案无法被抽象成通用库,只能针对具体场景自研。

八、结语

这场”框架 vs 裸写循环”的分歧,本质上是对当前模型能力阶段的一次判断:

当模型足够强,智能体的”智能”应该来自模型和提示词,而工程资源应该全部投向围绕循环的安全、可靠与可控——这个判断,头部产品已经用脚投票了。

对个人开发者的启示也很实际:如果你想做一个类似 Claude Code 的工具,不需要先学 LangGraph。打开厂商 API 文档,写下那个 while 循环,定义几个工具,写一份认真的系统提示词——你就已经站在和 Anthropic 同一条架构起跑线上了。剩下的差距,全在循环之外的那 98% 里,而那部分,框架同样不会替你写。


参考:Claude Code 源码逆向分析(如 “Claude Code: 1.6% AI, 98% Scaffolding” 系列)、Codex CLI 与 OpenCode 开源仓库、LangChain/LangGraph 官方文档及社区生产实践分享。