资讯动态

Claude Code源码拆解:Agent循环、工具调用与上下文管理

发布时间:2026/10/25 4:49:22 来源:尧图企业网站定制
有些代码泄漏吃瓜群众看的是热闹开发者看的才是门道。前段时间网上流传出的Claude Code源码在技术圈里炸了一圈。很多人第一反应是去翻代码找漏洞、找彩蛋但真正值得花时间的是把这个工业级AI Coding Agent从里到外拆一遍——看清楚它凭什么能在真实项目里自己读代码、改文件、跑命令、修错误而不是像大多数Demo那样只会聊天。这篇文章我会用这套源码作为引子带你把一个Agent的核心循环、工具系统、上下文管理、权限控制这几个关键模块逐个过一遍最后给一个可以自己抄作业的Mini版编码Agent骨架。适合三类人正在开发Agent产品的工程师、好奇Claude Code为什么好用的同学、以及想在自己的项目里接入编码Agent能力的架构师。1. 这次源码泄漏到底泄了什么一个不含大模型参数的Agent壳子1.1 事件背景与壳的含义先说清楚一件事网上流传的这套Claude Code源码里面并没有大模型权重也没有神秘的推理算法。它本质上是一层跑在Claude API外面的调度壳。Claude Code本身不是一个模型而是一个用Node.js/TypeScript写成的命令行程序它负责把用户的自然语言请求转换成一系列具体的行动——比如读文件、写文件、执行shell命令、调用外部API——然后通过Anthropic的API把上下文和工具定义发给Claude模型拿到模型的决策后再继续执行。打个比方。你问一辆超跑为什么跑得快你以为会看到发动机里的燃油配方和活塞工艺结果打开机舱盖发现有人把方向盘、行车电脑、油门踏板的标定逻辑全给你摊在桌子上了——发动机本体依然是黑盒。Claude Code的源码就是那套方向盘和行车电脑而发动机是Claude模型本身。这个区分非常重要。很多人一听Claude Code源码泄漏以为拿到了什么核心模型权重的碎片实际上拿到的是Anthropic团队在产品工程层面的大量心血Agent Loop的编排方式、系统提示词的设计、工具调用Schema的写法、权限交互逻辑、上下文压缩策略。这些才是从0到1复刻一个编码Agent时最容易被低估、也最难做对的部分。1.2 为什么工业级实现值得认真读市面上的AI编程助手已经很多了但大多数是IDE里多了一个补全框——你写一行它猜下一行本质上是tab补全的升级版。Claude Code和它们的区别在于它是一个真正的Agent被放到终端里拿到了执行命令和修改文件的权限。它能自己初始化一个项目、跑测试、看报错、再改代码直到测试通过。这个端到端闭环能力才是它在众多工具里显得特殊的原因。从热闹的搜索词也能看出来很多人已经在用Claude Code了——搜claude code安装教程claude code fdeclaude code 报错的人不在少数。但会用和懂原理是两码事。你安装好工具敲一句帮我修一下这个bug它背后到底怎么定位问题、怎么决定改哪个文件、怎么判断改完了没有——这些逻辑就是藏在源码和系统提示词里的工业级秘密。读这套源码不是为了复刻一个一模一样的竞品而是为了理解一个成熟产品在真实工程约束下做设计的方式。举个例子你写一个工具调用循环可能只需要几十行代码但要让这个循环在跑一整天、处理上千次工具调用时不崩、不跑偏、不泄露上下文、不被恶意命令坑就需要很多在Demo里根本不会出现的工程细节。2. Agent Loop让整个工具转起来的主循环与系统提示词设计2.1 ReAct循环的工程化实现思考、行动、观察要说Claude Code这类工具的核心绕不开ReActReasoning Acting模式。简单讲就是把推理和行动交替进行让模型每一步都基于新获得的信息继续做出判断而不是一次输出结论就完事。Claude Code的任务循环大致可以抽象成这样用户输入一句请求 → 模型生成一段回复中间夹带一个或多个工具调用→ 工具执行并返回结果 → 结果追加到对话历史 → 模型基于新的历史继续推理再生成下一步行为……直到模型认为任务已经完成不再请求工具而是输出最终答案。我举个具体例子。你在终端里对Claude Code说帮我把项目里的fetch换成axios。一个成熟的Agent不会直接回答好的我改了而是会先调用Grep找到哪些文件里用了fetch再调用Read打开对应文件确认上下文接着调用Edit把代码替换掉最后用Bash跑一遍lint或测试确认没有破坏东西。每一步都是一个完整的思考→行动→观察循环模型的推理不是一次性的而是跟着工具结果不断调整。这里最玄学但其实也最工程的是终止条件。模型什么时候停止调用工具开始输出答案不是靠一个计数器而是靠模型自己在生成时判断当前信息足够了。源码里做了一件事持续解析模型输出中是否包含工具调用请求。如果包含就执行工具并把结果追加回去如果不包含就认为链路结束了把最后一段非工具调用文本作为最终答案呈现给用户。2.2 系统提示词整个产品团队经验的浓缩网传源码里最值得逐字读的我认为不是算法而是那几万字的系统提示词。它基本就是整个Anthropic产品团队踩了无数坑之后总结出来的操作手册。系统提示词不包含任何模型权重但它决定了模型在具体场景下的行为边界和工作习惯。从泄漏出的内容能看出这几个核心指令方向第一要求Agenthands-on。收到问题后不要去问用户你想怎么做而是主动去查代码、找证据、自己形成判断。这和我见过的大多数AI助手产品形成了鲜明对比——很多工具收到请求后的第一反应是给建议而Claude Code被训练成先动手查再给结论。第二要求一次只做一个变更。完成一个目标之后再做下一个不要在一个工具调用里夹带一堆不相关的改动。这个设计很克制但它保证了一个长任务里每一步都是可审查、可回滚的。第三强调不能用工具验证的事要如实说明。系统提示词里有一类要求是禁止模型假装自己执行过某个命令、禁止编造工具输出结果。这条重要性怎么强调都不为过——Agent一旦开始表演整个闭环就失去了可靠性。工业级和玩具级之间往往就差这一点诚实。2.3 流式输出一边干活一边写工作日志使用过Claude Code的人都知道它的体验是边思考边打字你能实时看到它在读什么文件、执行什么命令、得到了什么结果。这看起来像是个体验优化背后其实是一套流式事件机制。源码层面Claude Code维护了一个内部的事件流。模型每次生成一段文本或者请求一个工具都会作为一个事件被推给前端界面渲染。这样做的工程价值有两点一是用户能感知到Agent在工作而不是对着空白屏幕干等二是事件流同时也构成了后续上下文的一部分——中间过程被完整记录下来模型在生成最终答案时能回溯自己做过什么。这一点还顺带解释了为什么Agent的token消耗比普通对话高得多。每一次工具调用、每一条工具结果、每一段中间推理都会累积到上下文里所以你在终端里用Claude Code跑一个复杂任务后台的token消耗往往很惊人。理解了这一点再看后文的上下文压缩机制就能明白为什么那是必备功能而不是加分功能。3. 工具调用从源码细看一个工业级Agent的手脚如何分工3.1 内置工具矩阵每个工具干一件事边界清楚Agent的行动能力全部来自它注册给模型的那批工具。Claude Code的工具集没有追求数量多而是每个工具的职责边界非常清楚。我从源码里梳理出来的核心工具大概是这样一张矩阵工具功能核心参数典型使用场景Read读取文件内容file_path, offset, limit查看某个文件的具体实现Write整文件写入file_path, content新建文件或整体覆盖Edit按行精确替换file_path, old_string, new_string局部修改代码Bash执行shell命令command, timeout跑测试、装依赖、启动服务Grep正则搜索文件内容pattern, path定位用例或函数定义Glob按模式匹配路径patternpath找文件、统计数据规模WebFetch抓取网页内容url查阅文档、确认API用法这张工具清单看起来简单但设计上有很深的考量。比如Edit工具不是整文件重写而是精确到old_string和new_string的局部替换。这样做的直接好处是省token——你改一行代码不需要把整个500行的文件重新发给模型另一个隐藏好处是更安全——局部diff比整体覆盖更容易被用户审查误改动的影响范围也被限制住了。再比如Read工具支持offset和limit参数也就是说你可以分段读取一个超大文件。这在处理动辄几千行的配置文件或自动生成代码时非常关键。工具参数的设计本质上是产品对模型行为的塑造——工具能怎么用模型就会怎么用。3.2 权限与安全危险操作前的一道道闸门工具能力越强风险越高。Bash工具能执行任意shell命令这既是Claude Code强悍的原因也是最容易出安全事故的点。源码里对工具的权限管理做了分类处理总体上可以总结成三个等级自动允许、需要确认、始终禁止。自动允许的一般是只读操作比如Read、Grep、Glob这类不会改变系统状态的工具。需要确认的则是Edit、Write这样会修改文件的操作以及Bash里的非只读命令。用户可以在交互界面里按y同意、按n拒绝也可以配置allow规则让某些频繁使用的安全命令自动放行。这套权限模型我用一个词来形容人在回路。它不追求完全自主而是在Agent能力和用户控制之间找一个平衡点。对任何做Agent产品的人来说这是个非常重要的设计参考——你给Agent的权限越大它的故障半径就越大而绝大多数用户在第一次看到Agent擅自执行rm命令时心里多少会有点发毛。我还注意到一个经验性的细节Bash工具的timeout参数是可以配置的。给长时间运行的命令设置超时可以避免Agent被一个永远不会结束的命令卡死。这类细节在Demo里没人提但在生产环境里处理不当会直接导致整个会话不可用。3.3 工具结果如何被消化工具调用返回的结果不是给用户看的而是作为新的对话历史追加给模型的。这个机制是Agent闭环里最基础的一环也是最容易被忽略的一环。模型生成一个工具调用后这个带工具调用的assistant消息会被放进历史消息列表然后每种工具的执行结果会以tool角色的消息追加到同一个列表里。模型的下一步推理会同时看到自己刚才调用了什么工具和工具返回了什么这两部分信息从而做出更准确的判断。这里面有个非常现实的工程问题工具输出可能很长。一次Grep如果匹配了200个文件返回的文本可能直接占掉几千token。源码里会对大输出做截断或摘要处理避免无意义的token浪费。对工具结果的消化程度直接影响Agent的上下文利用率和响应速度。另一个值得学习的细节是失败处理。源码里反复出现的一个原则是工具调用失败后不要盲目重试同样的事。合理的Agent行为是分析失败原因、换一个方案、尝试新的路径。如果连续失败两次就要停下来把情况告诉用户而不是无限循环。这个止损逻辑在很多自己搭Agent的项目里往往被遗漏。4. 上下文管理无限对话窗口背后的压缩、检索与状态维护4.1 不把项目塞进窗口按需检索策略新手设计AI编程助手时最容易犯的错误是想把整个项目都塞进上下文里让模型全知全能。这个思路在项目只有几十个文件时勉强能用一旦项目扩大到上千个文件光是一次完整读取的token量就能撑爆上下文窗口。Claude Code的做法是典型的按需检索面对一个大型代码库它不尝试一次性加载全部源码而是先通过Glob了解项目文件结构再用Grep定位关键符号最后用Read精确读取涉及的文件。这套组合拳保证了上下文里装的永远是和当前任务直接相关的信息而不是一堆无关代码。我举一个实际工作流的例子。当Claude Code需要修改一个API接口的返回值结构时它大概率会先用Grep搜索return {这类模式锁定候选代码位置再Read打开相关文件确认数据结构而不是从项目入口文件开始一字一字读。这个策略和我们人类工程师的工作方式高度一致——先定位再精读而不是从头到尾通读。有人在搜索词里问claude code 免费使用claude code安装教程其实这类问题背后暴露的是同一个痛点大家真的把Claude Code当成生产力工具来用了但很少有人关心它为什么能在大项目里稳定工作。答案就在这个按需检索策略里——它的上下文效率是通过克制换来的而不是靠更大的窗口。4.2 Compact机制对话太长了怎么办无论怎么按需检索一个任务持续久了历史消息还是会越积越长。Claude Code提供了一套压缩机制官方命令叫/compact。当对话历史超过设定的长度阈值时它会自动触发——把之前的对话历史浓缩成一个摘要替换掉原有的大段历史释放上下文空间。值得细看的是源码里对摘要格式的要求。摘要不是简单的一句话说用户改了一个bug而是要结构化成类似这样已完成哪些任务、当前在做什么、项目的关键路径是什么、待办事项有哪些。这个结构化摘要的质量直接决定压缩之后的Agent是否还能高效工作。我自己对比过摘要写得具体、可操作压缩后Agent基本不失忆摘要写得笼统压缩后同一个任务常常要重新摸索一遍。这个机制对长程任务的意义不言而喻。你在终端里让Claude Code开发一个新功能中间可能经历十几轮文件修改和测试执行如果每轮的历史都原封不动保留几轮下来上下文就会臃肿到影响模型判断。或者说上下文压缩不是为了省成本而是为了保证Agent在中后期仍然能聚焦在正确的目标上。4.3 状态维护比聊天记录更重要在Agent领域有一个普遍被低估的坑模型会记住聊过什么但不太会主动记住自己做到哪一步了。Claude Code在源码和系统提示词层面都做了一件事——要求Agent在任务过程中维护一个显式的进度状态比如待办清单、当前步骤、已完成步骤。这个设计和我们的直觉相反。我们总觉得上下文越长模型越不容易失忆但真实情况是如果不把关键状态从聊天记录里提取出来放到一个显眼的位置几千行历史消息反而会让模型迷失重点。显式状态维护相当于给Agent准备了便利贴把最重要的信息贴在桌面上而不是埋在那堆历史文件里。这一点我做自己的Agent时深有体会。早期版本里我只靠历史消息来维持任务进度经常出现的情况是模型在执行到第5步时忘了第1步定义的目标开始往错误方向发散。后来我在提示词里强制要求模型维护一个进度条每个回复开头都输出当前任务的完成状态发散问题明显减少。这不只是Claude Code的技巧这是任何长任务型Agent都应该具备的基本素养。5. 源码之外的可复用方案给自己造一个Mini Coding Agent5.1 直接可落地的骨架Python实现一个极简版读源码的最终目的是为了形成自己的判断。我不建议你去复刻一个Claude Code但我强烈建议你亲手搭一个Mini版——几百行代码就能跑起来的那种把核心循环吃透。下面这个Python骨架就是我建议的起点import json from your_llm_sdk import chat_with_tools # 替换为你用的模型SDK MAX_STEPS 10 def run_agent(user_request): messages [{role: user, content: user_request}] for step in range(MAX_STEPS): resp chat_with_tools(messages) msg resp.choices[0].message # 没有工具调用说明任务完成输出最终答案 if not msg.tool_calls: return msg.content # 把带工具调用的assistant消息放进历史 messages.append(msg) # 依次执行每个工具调用 for call in msg.tool_calls: result execute_tool(call.function.name, call.function.arguments) messages.append({ role: tool, tool_call_id: call.id, content: truncate(result, max_length3000) }) return 达到最大步数任务提前终止这个骨架的核心就一个while循环。你只要补上三样东西一个工具注册表、一个执行函数、一个上下文截断工具一个最简Agent就成型了。工具注册表长这样def execute_tool(name, args_json): args json.loads(args_json) if name read_file: with open(args[path]) as f: return f.read() if name grep: import subprocess return subprocess.run( [grep, -rn, args[pattern], args.get(path, .)], capture_outputTrue, textTrue ).stdout if name bash: import subprocess return subprocess.run( args[command], shellTrue, capture_outputTrue, textTrue ).stdout return f未知工具: {name}你只需要给模型提供对应的工具Schema它就会自动决定什么时候调用哪个工具。剩下的所有智能都是模型和工具之间通过对话循环碰出来的。5.2 必须处理的三个坑骨架搭起来很快但要让它真正稳定工作有三个坑绕不过去。第一个坑是工具结果不加控制地塞回上下文。我在前面提过Grep输出可能非常长如果不截断几轮下来上下文就满了。所以一定要给工具结果设置一个最大长度比如3000字符超出部分截断或者做摘要。宁可信息不完整也不能让上下文失控。第二个坑是Agent死循环。模型在某些场景下会反复调用同一个工具或者调用一个永远执行不完的命令。我的处理办法是设置最大迭代次数比如10轮超了就主动终止并把当前状态告诉用户。另外每个Bash命令都要设timeout防止命令阻塞整个会话。第三个坑是权限不分级。如果你把Bash工具的定义暴露给模型而不做任何限制那它在某些时候可能会执行危险命令。我的建议是只读操作自动放行写操作需要确认关键环境变量和系统目录直接列入黑名单。对个人项目可能无所谓但一旦你想把这个骨架接进公司代码库这条就是生死线。这几个坑看起来都是工程细节但正是它们把能跑和能用在生产环境区分开。Claude Code的源码里这类细节占了相当大的比重——这大概是工业级实现和学术Demo之间最直观的差别。5.3 关于换个底座模型的社区玩法顺着源码话题延伸一下很多人都在讨论Claude Code接入DeepSeek这类玩法搜索词里也能看到claude code接入deepseek v4这样的高频提问。原理上并不神秘Claude Code本质上是一个API Client它通过环境变量读取API地址和模型名把base_url和模型标识改掉就能把后端从Claude换成其他兼容模型。这个玩法的价值在于验证想法。你可以用一个更平价的模型把Claude Code做Agent的循环体验完整跑一遍看看自己是不是喜欢这种工作流。但你说要直接当生产力用我的态度是比较保守的。原因也很简单Claude Code那套系统提示词是专门为Claude模型设计的里面有很多针对Claude输出风格的隐含假设换成另一个模型后工具调用的格式兼容性、指令遵循程度、对长上下文的利用效率都会打折扣。不是所有模型都能稳定输出符合工具Schema的JSON也不是所有模型都愿意严格遵循一次只做一个变更之类的约束。所以我的实践结论是做实验、学原理用开源模型完全可以接生产环境本质是拿稳定性换成本这笔账要自己算清楚。尝试在这个骨架基础上做一次真实的任务比如让Agent自己初始化一个Python项目并跑通一个单测你会发现很多理想化的假设会当场碰壁。但恰恰是这些碰撞能让你真正理解Claude Code这类工业级产品背后那些看不见的工程有多值钱。我自己在仿照这套架构做了一个内部小工具之后最大的收获不是我会写Agent循环了而是深刻理解了工具设计对Agent体验的决定性作用。给模型越大的自由不等于越好的结果相反把动作收敛到几个精心设计的高质量工具上配合清晰的权限边界和克制的上下文管理Agent的表现反而稳定得多。下一个真正好用的Coding Agent大概不会赢在模型参数比谁更大而是赢在这套循环设计、工具边界和上下文治理的综合功力上。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑