发布时间:2026/9/7 23:06:19
AG-12_Agent 主循环:那个 while-loop 和它的护城河 Agent 主循环那个 while-loop 和它的护城河所有 AI Agent 的核心都是一个 while-loop。调模型跑工具把结果喂回去再调模型。听起来简单到令人怀疑——但正是这个简单的循环构成了今天最强编程助手最深的工程护城河。前言如果你去问任何一个 AI Agent 的架构师「你们的核心是什么」他们大概率会指着一段伪代码说「就这个 while-loop。」然后你会觉得很失望。一个循环一个while(true)这就是传说中的 AI Agent是的。但这就像说「火箭引擎就是个管子往后面喷火」一样——技术上正确但完全忽略了工程实现中的复杂度。在上一篇文章中我们从高空俯瞰了 Claude Code 的 25 个子系统。今天我们要深入到整个系统的绝对核心——Agent 主循环。这个循环是 Claude Code 乃至所有 Agent 系统的心脏理解它就理解了 Agent 工程的本质。Agent Loop 的本质在深入源码之前让我们先从理论层面理解 Agent Loop 的本质。2023 年Yao 等人在 ICLR 上发表的 ReAct 论文提出了一个关键洞察LLM 的推理Reasoning和行动Acting应该交替进行而不是分离。这个洞察直接催生了现代 Agent Loop 的基本范式while (任务未完成) { 1. 思考Think—— LLM 分析当前状态决定下一步行动 2. 行动Act—— 执行一个工具调用 3. 观察Observe—— 获取工具执行的结果 4. 将观察结果反馈给 LLM }这个循环的精妙之处在于每一轮迭代都在扩展 Agent 的知识。第一轮Agent 可能只知道用户的指令第二轮它可能已经读取了相关文件第三轮它可能已经执行了搜索命令并获得了结果。每一轮的观察结果都成为下一轮推理的输入。Claude Code 的 Agent Loop 在此基础上进行了大量工程化改造但核心逻辑完全一致。Claude Code 的核心循环实现让我们直接看源码。以下是根据 Claude Code v2.1.88 源码还原的核心循环实现// agent-loop/core.ts - Agent 主循环核心实现简化还原// 这是整个 Claude Code 最核心的代码所有功能都围绕这个循环展开interfaceAgentLoopState{messages:Message[];// 完整的对话历史context:ContextWindow;// 当前上下文窗口经过压缩turnCount:number;// 当前轮次totalTokens:number;// 累计消耗的 Token 数pendingToolCalls:ToolCall[];// 等待执行的工具调用}classAgentLoop{privatestate:AgentLoopState;privateconfig:AgentConfig;privatetools:ToolRegistry;privatepermissions:PermissionPolicy;privatecontextManager:ContextManager;privateapiClient:APIClient;asyncrun(initialPrompt:string):PromiseAgentResult{// 将用户的初始输入加入消息历史this.state.messages.push({role:user,content:initialPrompt,});// 核心循环开始 while(true){try{// 第一步上下文管理——确保消息不超过上下文窗口限制// 这是整个循环中最关键的工程决策之一this.state.contextawaitthis.contextManager.compress(this.state.messages,this.config.maxContextTokens);// 第二步调用 LLM API// 传入压缩后的上下文和所有可用工具的定义constresponseawaitthis.apiClient.createMessage({model:this.config.model,system:this.state.context.systemPrompt,messages:this.state.context.messages,tools:this.tools.getDefinitions(),// 注册的所有工具max_tokens:this.config.maxOutputTokens,stream:true,// 流式响应});// 第三步处理流式响应// Claude 可能在一次响应中混合文本和工具调用constprocessedResponseawaitthis.processStream(response);// 第四步将 assistant 的响应加入消息历史this.state.messages.push({role:assistant,content:processedResponse.content,});// 第五步检查是否有工具调用需要执行consttoolCallsextractToolCalls(processedResponse);if(toolCalls.length0){// 没有工具调用 LLM 认为任务完成或需要用户输入// 将响应展示给用户等待下一步指令this.displayResponse(processedResponse);constuserInputawaitthis.waitForUserInput();if(userInputnull){// 用户选择退出return{status:completed,messages:this.state.messages};}this.state.messages.push({role:user,content:userInput,});continue;// 继续循环}// 第六步执行所有工具调用// 注意某些工具调用可能需要用户确认权限系统consttoolResultsawaitthis.executeToolCalls(toolCalls);// 第七步将工具执行结果加入消息历史for(constresultoftoolResults){this.state.messages.push({role:user,// 工具结果以 user 消息的形式传回content:[{type:tool_result,tool_use_id:result.id,content:result.output,}],});}// 更新轮次计数和 Token 统计this.state.turnCount;this.state.totalTokensprocessedResponse.usage.total_tokens;// 第八步安全检查——防止无限循环if(this.state.turnCountthis.config.maxTurns){this.displayWarning(达到最大轮次限制自动停止);return{status:max_turns,messages:this.state.messages};}}catch(error){// 错误处理网络错误、API 限流、工具执行失败等constrecoveredawaitthis.handleError(error);if(!recovered){return{status:error,error,messages:this.state.messages};}// 如果恢复成功继续循环}}// 核心循环结束 }}这段代码虽然经过简化但已经完整呈现了 Claude Code Agent Loop 的核心逻辑。让我们逐一解析其中的关键设计决策。循环中的状态管理Agent Loop 的状态管理是整个系统中最微妙的部分。状态不仅包括消息历史还包括上下文窗口、Token 计数、工具调用状态等多个维度。// state/conversation.ts - 对话状态管理简化还原// 状态管理的核心挑战如何在有限的上下文窗口中维护尽可能多的有用信息interfaceConversationState{// 消息层 fullHistory:Message[];// 完整的消息历史可能超过上下文窗口activeContext:Message[];// 当前活跃的上下文在上下文窗口内// 工具状态层 activeTools:Mapstring,ToolExecution;// 正在执行的工具completedTools:ToolResult[];// 已完成的工具结果toolCallChain:ToolCallChain;// 工具调用链用于调试// 会话元数据 sessionId:string;// 会话唯一标识startTime:number;// 会话开始时间turnCount:number;// 当前轮次tokenUsage:TokenUsage;// Token 使用统计// 错误恢复状态 lastCheckpoint:Checkpoint;// 最近一次检查点用于会话恢复retryState:RetryState;// 重试状态避免重复失败的操作}classStateManager{// 创建检查点——在关键操作前保存状态快照// 这使得会话恢复成为可能asynccheckpoint(state:ConversationState):PromiseCheckpoint{constsnapshot:Checkpoint{id:generateId(),timestamp:Date.now(),messages:deepClone(state.fullHistory),metadata:{turnCount:state.turnCount,tokenUsage:state.tokenUsage,},};// 异步持久化到磁盘不阻塞主循环awaitthis.persistence.save(snapshot);returnsnapshot;}// 状态压缩——当消息历史过长时进行压缩// 这是上下文管理的核心操作asynccompress(state:ConversationState):PromiseConversationState{consttokenCountthis.countTokens(state.fullHistory);if(tokenCountthis.config.maxContextTokens){returnstate;// 未超过限制无需压缩}// 压缩策略保留系统提示 最近 N 轮 关键工具结果摘要constcompressedawaitthis.contextManager.compress(state.fullHistory);return{...state,activeContext:compressed,// 注意fullHistory 仍然保留完整历史只是 activeContext 被压缩了};}}这里有一个重要的设计决策fullHistory 和 activeContext 的分离。完整历史始终保留在内存中或持久化到磁盘但只有 activeContext 会被发送给 LLM。这种设计使得会话恢复成为可能——即使 activeContext 被压缩了完整历史仍然可用调试追踪可以回溯到任何一轮的完整状态压缩是有损的但可逆的——如果需要可以从 fullHistory 重新构建 activeContext错误处理与重试在生产环境中Agent Loop 面临的错误类型远比想象中多样// agent-loop/error-handler.ts - 错误处理与重试策略简化还原// 这个模块体现了「在生产环境中一切都会出错」的工程信念classAgentErrorHandler{// 错误分类——不同类型的错误需要不同的处理策略privateclassifyError(error:Error):ErrorCategory{if(errorinstanceofAPIRateLimitError){return{type:rate_limit,retryable:true,backoff:exponential};}if(errorinstanceofAPITimeoutError){return{type:timeout,retryable:true,backoff:linear};}if(errorinstanceofContextWindowExceededError){return{type:context_overflow,retryable:true,backoff:compress};}if(errorinstanceofToolExecutionError){// 工具执行错误需要特殊处理——可能是权限问题也可能是工具本身的 bugreturn{type:tool_error,retryable:this.isToolRetryable(error),backoff:none};}if(errorinstanceofAuthenticationError){return{type:auth,retryable:false,backoff:none};}return{type:unknown,retryable:false,backoff:none};}asynchandleError(error:Error,state:AgentLoopState):PromiseRecoveryResult{constcategorythis.classifyError(error);switch(category.type){caserate_limit:// 限流错误等待 Retry-After 头指定的时间后重试constretryAftererror.retryAfter||60;awaitthis.sleep(retryAfter*1000);return{recovered:true,action:retry};casecontext_overflow:// 上下文溢出触发紧急压缩然后重试state.contextawaitthis.contextManager.emergencyCompress(state.messages,// 紧急压缩会更激进地裁剪历史{aggressive:true,preserveSystemPrompt:true});return{recovered:true,action:retry_with_compressed_context};casetool_error:// 工具错误将错误信息作为工具结果返回给 LLM// 让 LLM 自己决定如何处理——这是 ReAct 模式的精髓consttoolResult:ToolResult{tool_use_id:error.toolCallId,content:Error:${error.message},is_error:true,};state.messages.push({role:user,content:[{type:tool_result,...toolResult}],});return{recovered:true,action:continue_with_error};caseauth:// 认证错误无法自动恢复需要用户介入this.ui.displayError(认证失败请检查 API Key 或重新登录);return{recovered:false,action:abort};default:// 未知错误记录日志尝试有限次数的重试if(state.retryCountthis.config.maxRetries){state.retryCount;awaitthis.sleep(1000*state.retryCount);return{recovered:true,action:retry};}return{recovered:false,action:abort};}}}这段代码中最值得关注的设计是工具错误的处理方式当一个工具执行失败时Claude Code 不会简单地重试或终止而是将错误信息作为工具结果返回给 LLM。这体现了 ReAct 模式的一个核心优势——LLM 可以理解错误并自主决定下一步行动。比如如果git commit失败因为有未暂存的更改LLM 可能会决定先执行git add再重试。代码示例核心循环伪代码还原为了帮助理解让我们用更简洁的伪代码形式还原 Agent Loop 的核心逻辑# agent_loop_pseudocode.py - Agent 主循环伪代码# 这段伪代码浓缩了 Claude Code Agent Loop 的核心思想# 去掉了所有工程细节只保留了最本质的逻辑defagent_loop(user_message:str,tools:list[Tool])-str:Agent 主循环 - 所有 AI Agent 的心脏# 初始化状态messages[Message(roleuser,contentuser_message)]turn_count0whileTrue:# 第一步上下文压缩 # 如果消息总 Token 数超过上下文窗口限制进行压缩# 压缩策略包括消息裁剪、工具结果截断、历史摘要等ifcount_tokens(messages)MAX_CONTEXT_TOKENS:messagescontext_manager.compress(messages)# 第二步调用 LLM # 将消息历史和工具定义发送给 Claude API# 使用流式响应以提供实时反馈responseclaude_api.create_message(messagesmessages,toolstools,# 所有可用工具的定义systemSYSTEM_PROMPT,# 系统提示词streamTrue,# 流式响应)# 第三步解析响应 # Claude 的响应可能包含文本和工具调用的混合text_contentextract_text(response)tool_callsextract_tool_calls(response)# 将 assistant 的响应加入消息历史messages.append(Message(roleassistant,contentresponse.content))# 第四步判断是否需要继续 ifnottool_calls:# 没有工具调用 LLM 认为任务完成# 展示响应等待用户输入display(text_content)user_inputwait_for_input()ifuser_inputisNone:returnSession endedmessages.append(Message(roleuser,contentuser_input))continue# 继续循环处理用户的下一条消息# 第五步执行工具调用 fortool_callintool_calls:# 权限检查某些操作需要用户确认ifneeds_permission(tool_call):grantedask_user_permission(tool_call)ifnotgranted:# 用户拒绝了操作将拒绝信息反馈给 LLMmessages.append(create_tool_result(tool_call,Permission denied by user,is_errorTrue))continue# 执行工具try:resultexecute_tool(tool_call)exceptToolErrorase:# 工具执行失败将错误信息反馈给 LLM# LLM 会理解错误并决定下一步行动resultcreate_tool_result(tool_call,str(e),is_errorTrue)# 将工具结果加入消息历史messages.append(create_tool_result(tool_call,result))# 第六步安全检查 turn_count1ifturn_countMAX_TURNS:returnReached maximum turns# 循环回到第一步开始下一轮这段伪代码清晰地展示了 Agent Loop 的六个核心步骤上下文压缩 → 调用 LLM → 解析响应 → 判断继续 → 执行工具 → 安全检查。整个循环就是这六个步骤的不断重复。为什么 while-loop 是护城河看到这里你可能会问既然 Agent Loop 的逻辑这么简单为什么说它是护城河答案在于简单的循环逻辑 × 复杂的工程实现 巨大的护城河。让我用一个对比表格来说明维度学术论文中的 Agent LoopClaude Code 的 Agent Loop上下文管理假设无限上下文窗口五层压缩管线动态裁剪错误处理忽略或简单重试分类错误 智能恢复 LLM 自主决策工具执行同步、无超时异步、超时、重试、并行状态管理内存中的简单列表持久化、检查点、会话恢复安全控制无权限系统 沙箱 审计日志用户交互一次性输入输出多轮对话 实时反馈 打断生产就绪度原型级别数百万用户级别每一个「看起来简单」的步骤在生产环境中都需要大量的工程工作「调用 LLM」需要处理流式响应、超时重试、限流退避、模型切换「执行工具」需要权限校验、沙箱隔离、超时控制、并行执行「将结果喂回去」需要上下文压缩、Token 计数、消息格式转换「判断是否继续」需要处理用户中断、最大轮次限制、错误恢复这些工程细节的累积构成了巨大的护城河。一个团队可以复制 Claude Code 的循环逻辑但要复制它的工程成熟度需要数月甚至数年的迭代。护城河的三个层次技术护城河五层上下文压缩管线、智能错误恢复、流式处理优化——这些技术实现需要深入理解 LLM 的行为特性和生产环境的约束。数据护城河数百万用户的使用数据使得 Anthropic 可以持续优化循环中的每一个决策点——什么时候压缩、什么时候重试、什么时候询问用户。迭代护城河每一个生产环境中的 bug 和 edge case都会被转化为循环中的防御性代码。这些代码是时间的结晶无法被简单复制。总结Agent 主循环是 Claude Code 乃至所有 AI Agent 系统的核心。它看起来简单——一个 while-loop调模型跑工具喂结果——但在生产环境中的工程实现却极其复杂。通过本章的源码分析我们可以看到Agent Loop 的本质是 ReAct 模式的工程化实现思考 → 行动 → 观察 → 重复状态管理是循环中最微妙的部分fullHistory 和 activeContext 的分离是有意为之的设计错误处理不是事后添加的功能而是循环的核心逻辑工具错误被反馈给 LLM 让其自主决策简单的循环逻辑 × 复杂的工程实现 巨大的护城河在下一篇文章中我们将聚焦于 Claude Code 的启动链路——从用户输入claude命令到 Agent Loop 开始运行之间发生了什么。参考资料Claude Code v2.1.88 源码分析— 基于 2025 年 3 月泄露的 npm 包逆向分析Yao, S. et al. (2023). “ReAct: Synergizing Reasoning and Acting in Language Models”— ICLR 2023 — Agent Loop 的理论基础Anthropic (2024). “Tool Use (Function Calling) with Claude”— https://docs.anthropic.com/en/docs/tool-use — Claude 工具调用的官方文档Shinn, N. et al. (2023). “Reflexion: Language Agents with Verbal Reinforcement Learning”— NeurIPS 2023 — Agent 错误处理与自我反思的理论基础Anthropic (2025). “Claude Code Best Practices”— https://www.anthropic.com/engineering/claude-code-best-practices — Claude Code 工程实践的官方分享本文是「Claude Code 源码深度解析」系列的第二篇。下一篇文章将聚焦于启动链路——从claude命令到 Agent Loop 启动之间的完整初始化过程。本系列覆盖AI 大模型基础、Agent 开发、MCP 协议、Skill 开发、RAG、模型微调、部署推理七大方向从入门到实战的全栈内容持续更新中。所有文章的 Markdown 源文件、可运行代码、高清配图已整理成完整资料包。 点赞 ⭐ 关注评论区扣「1」挨个发你领取方式

相关新闻

2026/9/7 23:06:19

香港假冒客服电话诈骗的生成机理与治理路径研究

摘要电话诈骗已经成为香港社会治安领域最为突出的犯罪类型之一,其中假冒客户服务人员的诈骗手法占据核心位置。2026 年上半年数据显示,香港电话诈骗案件数量同比上升百分之四十五至四千八百三十宗,损失金额同比上升百分之五十六至九亿港元&am…

2026/9/7 23:01:19

COSCon‘25 OpenGood论坛:开源公益如何用开放协作重构数字公共品

COSCon25 OpenGood 论坛议程出来了,开源公益这条路终于有人认真趟了每年这个时候,开源圈的老朋友们就开始盯着 COSCon 的议程表刷屏。今年我特别关注的是 OpenGood 开源公益论坛,看到议程正式发布的那一刻,说实话心里挺感慨的。过…

2026/9/8 3:52:09

内核驱动开发最难啃的硬骨头:片上资源管理框架详解

1. 为什么说片上资源管理是驱动开发里最难啃的硬骨头我学内核走到这一篇之前,一直自认为对驱动开发已经有了基本概念:写个 hello world 模块、操作几个寄存器、处理个中断,这些都是常规操作。但真正开始在嵌入式 Linux 平台上写商用驱动时&am…

2026/9/8 3:52:09

LabVIEW与VISA串口通信在四工位转盘检测机中的应用实践

做自动检测设备的朋友应该都清楚,凡是配上转盘的项目,十有八九都在跟节拍较劲。前段时间一个四工位转盘检测机的上位机项目,让我把LabVIEW、VISA和串口通信这几个老组合重新啃了一遍。设备本身不复杂:工控机上有两个串口&#xff…

2026/9/8 3:52:09

无线高压电池系统:从线束困局到无缆化BMS的工程实践

做电池包开发的同行应该都有过这种体验:一台CTP或大模组电池包下线,先不提电芯一致性,光包内那套低压采样线束就够折腾一阵了。从模组电压采样线、温度传感器线、均衡线,到从控到主控的菊花链通信线,一个Pack里动辄上百…

2026/9/8 3:52:09

基于UG的椭圆轴类组合件数控车削工艺设计全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/8 3:47:09

汽车电子软件入门:从ECU分层到CAN开发实践

汽车电子这个系列写到第3篇,按理说前两篇已经聊过整车电子电气架构和硬件平台选型,这一篇得把镜头拉近,专门聊软件。如果你正准备进车载嵌入式开发,或者已经在做传统MCU软件想往汽车行业转,这篇可以当作一份“从整车视…

2026/9/7 0:47:43

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/7 0:14:19

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/7 0:14:17

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/8 0:01:49

踩多轮坑才跑通|OpenClaw 3.1.0 双平台本地 AI 自动化搭建实操实录

🔹 工具简述 OpenClaw 是一款备受开发者与办公人群青睐的开源本地智能工具,凭借离线本地运行、可视化图形面板、全流程自主任务处理三大核心特点,积累了众多忠实用户。与普通对话类 AI 产品不同,它能够直接调用电脑的软硬件操作权…

2026/9/8 0:01:50

拒绝复杂命令行,Hermes Agent 一键包快速解锁智能办公能力

🔍前言 不少想要体验 Hermes Agent 办公能力的使用者,往往会被复杂的环境配置拦住使用脚步。手动下载匹配依赖、反复调整系统目录、处理命令行持续报错、修复权限异常、补全丢失核心文件等一系列操作,对普通使用者而言门槛较高,很…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/7 22:45:59

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…