010、Claude Code 架构概览Agent SDK、Tool System、MCP Server 生态全景上周五凌晨三点我在排查一个诡异的CI流水线超时问题。Claude Code在生成Kubernetes部署配置时突然卡在“正在调用kubectl工具”这一步整整挂了12分钟。我盯着终端日志发现它调用了三次kubectl get pods每次间隔五分钟——这不是网络问题是Tool System的调用策略出了岔子。这个坑让我意识到如果不把Claude Code的底层架构摸透所谓的“AI工程化”就是空中楼阁。今天这篇笔记我会从Agent SDK、Tool System、MCP Server三个维度把这张架构全景图拆开揉碎。Agent SDK不是你想的那样很多人以为Claude Code的Agent SDK就是个封装好的API调用库。错了。它本质上是一个状态机驱动的执行引擎核心是AgentLoop——一个不断循环的“感知-推理-行动”闭环。看一段我实际调试过的伪代码别在生产环境直接抄# 这是Claude Code Agent SDK的核心循环简化版classAgentLoop:def__init__(self,tools:List[Tool],max_steps:int25):self.toolstools# 这里踩过坑tools顺序影响推理效率self.max_stepsmax_steps self.history[]asyncdefrun(self,task:str):forstepinrange(self.max_steps):# 感知阶段把历史对话和工具调用结果拼成上下文contextself._build_context(task,self.history)# 推理阶段调用Claude模型生成下一步动作actionawaitself._reason(context)# 行动阶段执行工具调用或返回最终答案ifaction.typefinal_answer:returnaction.content resultawaitself._execute_tool(action)self.history.append((action,result))注意那个max_steps25——这是Claude Code的默认值但我在实际项目中改成了15。为什么因为超过15步的推理链错误率会指数级上升。模型会在第18步左右开始“编造”工具调用结果这是我在日志里亲眼看到的。Agent SDK里还有个容易被忽略的东西Tool Registry。它不是简单的工具列表而是一个带优先级和依赖关系的注册表。比如read_file和search_code这两个工具如果search_code先注册Claude Code会倾向于先搜索再读取而不是反过来。这个顺序直接影响调试效率。Tool System别被“工具”两个字骗了Tool System是Claude Code最容易被低估的模块。它不只是“调用外部命令”而是一个带重试、回滚、并发控制的执行沙箱。我遇到过最坑的场景Claude Code同时调用了git commit和npm install结果两个工具竞争同一个锁文件导致仓库状态损坏。后来我翻源码才发现Tool System默认是串行执行的但某些工具比如execute_command被标记为“可并行”——这个标记是工具开发者手动加的不是自动检测的。# Tool System的并发控制我改过的版本classToolExecutor:def__init__(self,max_concurrent:int1):# 别这样写默认1太保守self.semaphoreasyncio.Semaphore(max_concurrent)self.lock_registry{}# 文件锁注册表asyncdefexecute(self,tool_call:ToolCall):# 检查工具是否声明了锁资源iftool_call.tool.lock_key:asyncwithself.lock_registry.get_lock(tool_call.tool.lock_key):returnawaitself._do_execute(tool_call)else:asyncwithself.semaphore:returnawaitself._do_execute(tool_call)这里有个经验永远不要相信工具的“可并行”标记。我在生产环境强制所有文件系统操作串行执行虽然慢了点但再也没出现过竞态条件。Tool System的另一个关键设计是结果缓存。Claude Code会缓存工具调用的输出默认TTL是300秒。这个缓存粒度很粗——只要工具名称和参数完全一致就命中缓存。但问题来了kubectl get pods -n default和kubectl get pods --namespace default在Claude Code看来是两个不同的调用缓存不共享。我写了个小脚本在工具注册时对参数做规范化处理把缓存命中率从30%提到了70%。MCP Server生态混乱中的秩序MCPModel Context ProtocolServer是Claude Code的“外挂”系统。它允许你自定义工具、资源、提示模板但生态目前还处于“西部拓荒”阶段。我维护着一个内部MCP Server仓库里面大概有40多个自定义工具。踩过的坑可以写本书第一个坑MCP Server的生命周期管理。Claude Code默认会在启动时加载所有注册的MCP Server但如果某个Server挂了整个Agent会卡死。我写了个健康检查中间件# MCP Server健康检查别在生产环境省略这一步classHealthCheckMiddleware:def__init__(self,timeout:float5.0):self.timeouttimeout self.failure_count{}asyncdefwrap(self,server_name:str,call_func):try:resultawaitasyncio.wait_for(call_func(),timeoutself.timeout)self.failure_count[server_name]0returnresultexceptasyncio.TimeoutError:self.failure_count[server_name]1ifself.failure_count[server_name]3:# 连续失败3次自动降级return{error:fMCP Server{server_name}已降级}raise第二个坑MCP Server的协议版本兼容性。Claude Code的MCP协议版本是0.1.0但社区很多Server用的是0.2.0。版本不匹配时Claude Code会静默忽略整个Server——没有任何日志。我花了三天才找到原因最后在Claude Code的启动参数里加了--mcp-log-leveldebug才看到错误信息。第三个坑工具命名冲突。两个MCP Server都注册了search工具Claude Code会随机选择一个。解决方案是在工具名前加Server前缀比如github_search和jira_search。这个命名规范我现在强制团队执行。架构全景三者的协作关系把Agent SDK、Tool System、MCP Server放在一起看它们的协作关系是这样的Agent SDK是大脑负责决策“下一步做什么”。它把决策结果比如“调用kubectl get pods”发给Tool System。Tool System是肌肉负责执行“怎么做”。它从MCP Server注册表中查找对应的工具实现执行并返回结果。MCP Server是器官提供“能做什么”的能力。每个Server可以注册多个工具、多个资源模板。这个架构有个隐含问题Agent SDK对Tool System的调用是同步阻塞的。如果Tool System在执行一个耗时操作比如部署到K8s集群Agent SDK会一直等待无法并行处理其他任务。我在生产环境用了一个异步包装器把长时间运行的工具调用放到后台任务Agent SDK可以继续处理其他工具调用——但代价是推理质量下降因为模型需要同时跟踪多个异步任务的状态。个人经验别迷信默认配置。Claude Code的默认max_steps25、默认并发数1、默认缓存TTL300秒这些值都是针对通用场景的。你的项目可能需要完全不同的参数。我建议从max_steps10开始逐步增加直到找到推理质量和执行时间的平衡点。日志是调试的第一生产力。在Claude Code的启动参数里加上--log-leveldebug --tool-log-leveldebug --mcp-log-leveldebug你会看到工具调用的完整链路。这个配置在CI环境里尤其重要——我靠它抓到了至少20个隐藏bug。MCP Server的版本锁定。在项目的claude.code.json里明确指定每个MCP Server的版本号不要用latest标签。我见过因为MCP Server自动更新导致整个流水线崩溃的案例。工具调用的幂等性设计。任何可能被重复调用的工具比如创建资源、发送通知都要实现幂等性。Claude Code的重试机制会无差别重试所有失败的工具调用如果你的工具不是幂等的后果很严重。监控Agent的“思维链”。我写了个小工具把Agent SDK的推理过程实时输出到Grafana仪表盘。当模型开始重复调用同一个工具、或者调用间隔突然变长时就是出问题的前兆。这个监控帮我提前发现了三次潜在的无限循环。Claude Code的架构还在快速演进但Agent SDK、Tool System、MCP Server这个三层结构短期内不会变。理解它们各自的职责和协作方式是做好AI工程化的第一步。下一篇我会深入Tool System的缓存策略——那个坑比你想的深得多。
010、Claude Code 架构概览:Agent SDK、Tool System、MCP Server 生态全景
010、Claude Code 架构概览Agent SDK、Tool System、MCP Server 生态全景上周五凌晨三点我在排查一个诡异的CI流水线超时问题。Claude Code在生成Kubernetes部署配置时突然卡在“正在调用kubectl工具”这一步整整挂了12分钟。我盯着终端日志发现它调用了三次kubectl get pods每次间隔五分钟——这不是网络问题是Tool System的调用策略出了岔子。这个坑让我意识到如果不把Claude Code的底层架构摸透所谓的“AI工程化”就是空中楼阁。今天这篇笔记我会从Agent SDK、Tool System、MCP Server三个维度把这张架构全景图拆开揉碎。Agent SDK不是你想的那样很多人以为Claude Code的Agent SDK就是个封装好的API调用库。错了。它本质上是一个状态机驱动的执行引擎核心是AgentLoop——一个不断循环的“感知-推理-行动”闭环。看一段我实际调试过的伪代码别在生产环境直接抄# 这是Claude Code Agent SDK的核心循环简化版classAgentLoop:def__init__(self,tools:List[Tool],max_steps:int25):self.toolstools# 这里踩过坑tools顺序影响推理效率self.max_stepsmax_steps self.history[]asyncdefrun(self,task:str):forstepinrange(self.max_steps):# 感知阶段把历史对话和工具调用结果拼成上下文contextself._build_context(task,self.history)# 推理阶段调用Claude模型生成下一步动作actionawaitself._reason(context)# 行动阶段执行工具调用或返回最终答案ifaction.typefinal_answer:returnaction.content resultawaitself._execute_tool(action)self.history.append((action,result))注意那个max_steps25——这是Claude Code的默认值但我在实际项目中改成了15。为什么因为超过15步的推理链错误率会指数级上升。模型会在第18步左右开始“编造”工具调用结果这是我在日志里亲眼看到的。Agent SDK里还有个容易被忽略的东西Tool Registry。它不是简单的工具列表而是一个带优先级和依赖关系的注册表。比如read_file和search_code这两个工具如果search_code先注册Claude Code会倾向于先搜索再读取而不是反过来。这个顺序直接影响调试效率。Tool System别被“工具”两个字骗了Tool System是Claude Code最容易被低估的模块。它不只是“调用外部命令”而是一个带重试、回滚、并发控制的执行沙箱。我遇到过最坑的场景Claude Code同时调用了git commit和npm install结果两个工具竞争同一个锁文件导致仓库状态损坏。后来我翻源码才发现Tool System默认是串行执行的但某些工具比如execute_command被标记为“可并行”——这个标记是工具开发者手动加的不是自动检测的。# Tool System的并发控制我改过的版本classToolExecutor:def__init__(self,max_concurrent:int1):# 别这样写默认1太保守self.semaphoreasyncio.Semaphore(max_concurrent)self.lock_registry{}# 文件锁注册表asyncdefexecute(self,tool_call:ToolCall):# 检查工具是否声明了锁资源iftool_call.tool.lock_key:asyncwithself.lock_registry.get_lock(tool_call.tool.lock_key):returnawaitself._do_execute(tool_call)else:asyncwithself.semaphore:returnawaitself._do_execute(tool_call)这里有个经验永远不要相信工具的“可并行”标记。我在生产环境强制所有文件系统操作串行执行虽然慢了点但再也没出现过竞态条件。Tool System的另一个关键设计是结果缓存。Claude Code会缓存工具调用的输出默认TTL是300秒。这个缓存粒度很粗——只要工具名称和参数完全一致就命中缓存。但问题来了kubectl get pods -n default和kubectl get pods --namespace default在Claude Code看来是两个不同的调用缓存不共享。我写了个小脚本在工具注册时对参数做规范化处理把缓存命中率从30%提到了70%。MCP Server生态混乱中的秩序MCPModel Context ProtocolServer是Claude Code的“外挂”系统。它允许你自定义工具、资源、提示模板但生态目前还处于“西部拓荒”阶段。我维护着一个内部MCP Server仓库里面大概有40多个自定义工具。踩过的坑可以写本书第一个坑MCP Server的生命周期管理。Claude Code默认会在启动时加载所有注册的MCP Server但如果某个Server挂了整个Agent会卡死。我写了个健康检查中间件# MCP Server健康检查别在生产环境省略这一步classHealthCheckMiddleware:def__init__(self,timeout:float5.0):self.timeouttimeout self.failure_count{}asyncdefwrap(self,server_name:str,call_func):try:resultawaitasyncio.wait_for(call_func(),timeoutself.timeout)self.failure_count[server_name]0returnresultexceptasyncio.TimeoutError:self.failure_count[server_name]1ifself.failure_count[server_name]3:# 连续失败3次自动降级return{error:fMCP Server{server_name}已降级}raise第二个坑MCP Server的协议版本兼容性。Claude Code的MCP协议版本是0.1.0但社区很多Server用的是0.2.0。版本不匹配时Claude Code会静默忽略整个Server——没有任何日志。我花了三天才找到原因最后在Claude Code的启动参数里加了--mcp-log-leveldebug才看到错误信息。第三个坑工具命名冲突。两个MCP Server都注册了search工具Claude Code会随机选择一个。解决方案是在工具名前加Server前缀比如github_search和jira_search。这个命名规范我现在强制团队执行。架构全景三者的协作关系把Agent SDK、Tool System、MCP Server放在一起看它们的协作关系是这样的Agent SDK是大脑负责决策“下一步做什么”。它把决策结果比如“调用kubectl get pods”发给Tool System。Tool System是肌肉负责执行“怎么做”。它从MCP Server注册表中查找对应的工具实现执行并返回结果。MCP Server是器官提供“能做什么”的能力。每个Server可以注册多个工具、多个资源模板。这个架构有个隐含问题Agent SDK对Tool System的调用是同步阻塞的。如果Tool System在执行一个耗时操作比如部署到K8s集群Agent SDK会一直等待无法并行处理其他任务。我在生产环境用了一个异步包装器把长时间运行的工具调用放到后台任务Agent SDK可以继续处理其他工具调用——但代价是推理质量下降因为模型需要同时跟踪多个异步任务的状态。个人经验别迷信默认配置。Claude Code的默认max_steps25、默认并发数1、默认缓存TTL300秒这些值都是针对通用场景的。你的项目可能需要完全不同的参数。我建议从max_steps10开始逐步增加直到找到推理质量和执行时间的平衡点。日志是调试的第一生产力。在Claude Code的启动参数里加上--log-leveldebug --tool-log-leveldebug --mcp-log-leveldebug你会看到工具调用的完整链路。这个配置在CI环境里尤其重要——我靠它抓到了至少20个隐藏bug。MCP Server的版本锁定。在项目的claude.code.json里明确指定每个MCP Server的版本号不要用latest标签。我见过因为MCP Server自动更新导致整个流水线崩溃的案例。工具调用的幂等性设计。任何可能被重复调用的工具比如创建资源、发送通知都要实现幂等性。Claude Code的重试机制会无差别重试所有失败的工具调用如果你的工具不是幂等的后果很严重。监控Agent的“思维链”。我写了个小工具把Agent SDK的推理过程实时输出到Grafana仪表盘。当模型开始重复调用同一个工具、或者调用间隔突然变长时就是出问题的前兆。这个监控帮我提前发现了三次潜在的无限循环。Claude Code的架构还在快速演进但Agent SDK、Tool System、MCP Server这个三层结构短期内不会变。理解它们各自的职责和协作方式是做好AI工程化的第一步。下一篇我会深入Tool System的缓存策略——那个坑比你想的深得多。