生产级Agent的5层脚手架:用Claude Code搭稳定可控的AI系统
上个月参加了一场 Anthropic 工程师主持的工作坊议题是用 Claude Code 搭生产级 Agent。我原以为会上会有一堆提示词技巧或者模型参数调优的内容结果工程师在白板上写了第一句话Agent is a software architecture problem, not a model problem。整场三小时就围绕这句话展开——把 Agent 拆成五层脚手架逐层讲机制、讲取舍、讲实际项目里翻车的案例。这篇内容是那天的完整梳理加上我自己的实测补充给正在用 Claude Code 做 Agent 落地的团队一份可以直接对照的骨架笔记。这套五层结构从上到下分别是连接与上下文层、工具与技能层、记忆层、安全与治理层、编排与控制层。每一层在 Claude Code 里都有对应的原生机制连接层对应模型路由与重试策略工具层对应 Skill、子代理和 MCP记忆层对应 CLAUDE.md 和会话管理安全层对应权限模式与审计钩子编排层对应 Agent 循环和 checkpoint 设计。下面按工作坊的顺序逐层拆每层都会给出我验证过的配置和踩坑记录。1. 工作坊没讲模型讲的是脚手架工作坊一开始工程师先纠正了一个普遍的动作很多团队选 Agent 方案时第一反应是换框架。今天用 LangChain明天换 AutoGPT后天看到编排器又冒出来一个。他说这种思路本质上是把 Agent 当成一个函数库而这个思路会在生产环境里反复撞墙。脚手架的意义在于它不是楼本身是你盖楼时的支撑结构。楼可以换成任何业务形态脚手架的结构却是高度稳定的。框架的隐喻是房子已经盖好了你搬进去住脚手架的隐喻是楼还在盖但每一层的承重、通道和安全网都已经到位。生产级 Agent 从来不是一次性交付的成品它会随业务反复迭代所以你的投资应该放在那个能一直复用、不断加固的骨架上而不是某一版具体的业务流程。当天发的手册里有一张表把五层脚手架对应到缺失时的典型故障症状。这张表我后来一直贴在项目 wiki 的最上面层级核心职责缺失时的典型症状连接与上下文模型可达、输入输出可控频繁 403/超时、上下文溢出、输出截断工具与技能在权限边界内执行原子动作工具调用错乱、请求产生意外副作用记忆跨会话延续身份与状态每次重新开始、重复踩同一个坑安全治理最小权限、行为可溯误删文件、密钥泄露、越权操作编排控制拆解任务、约束循环Agent 卡死、无限重试、改错文件工程师说了一句我印象很深的话你们遇到的 90% 的 Agent 翻车事故不是模型能力不够是某一层脚手架没搭。比如收到 unable to connect to anthropic services 的第一反应是换模型但多数时候是一次连接层故障上下文爆了就无脑加长窗口结果窗口越大检索效率越低工具权限给太宽导致删错文件然后归咎于 AI 不靠谱没有审计日志出了问题连 Agent 刚才干了什么都不知道。这几类事故我后来在团队里全都遇到过无一例外。2. 第一层连接与上下文Agent 的地基2.1 连接层的三件事认证、重试、路由连接层的核心目标就一句话让 Agent 在一个稳定、可诊断的通道上拿到模型响应。工作坊直接放了一条工单记录一条 failed to connect to api.anthropic.com: status 403 的报错挂了三天没人处理因为大家默认是网络问题。实际排查下来是 CI 环境里 ANTHROPIC_API_KEY 过期了某个回滚操作把旧密钥带了回来。工程师给了一个很朴素的排查顺序先确认故障发生在哪一段。第一步用 curl 直接打一次 Messages API排除 Claude Code 本身的问题curl -v https://api.anthropic.com/v1/messages \ -H x-api-key: ${ANTHROPIC_API_KEY} \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d {model:你的模型ID,max_tokens:1024,messages:[{role:user,content:ping}]}curl 成功但 Claude Code 失败问题大概率出在 Claude Code 的配置、环境变量或者权限设置上curl 本身返回 403那就按认证链路查——密钥是否过期、账号是否还有额度、组织策略是否允许当前项目接入。如果错误里明确提示当前地区不受支持这类限制信息这是产品策略和合规限制不是配置 bug工程上的合法思路是走企业版或官方支持渠道而不是试图绕过去。重试策略也在这层做。生产环境里不要依赖默认行为建议在调度侧加退避重试。我的做法是给定时任务套一层外壳第一次失败等 5 秒第二次 10 秒第三次 30 秒超过三次直接熔断并告警不带着坏连接反复空转。模型路由也属于连接层。工作坊给的分工很明确规划、架构评审这类高推理密度任务用顶配模型日常代码生成和修复用均衡型号分类、总结、上下文压缩这类重复任务交给小模型。Claude Code 里既可以在会话内用 /model 切换也可以用 --model 指定启动模型。另外它做自动压缩上下文时会额外调一个小模型你可以用 ANTHROPIC_SMALL_FAST_MODEL 指向一个便宜快速的型号避免压缩这一步也吃主模型的 token。2.2 上下文层200k 是上限不是预算工程师反复强调一句话上下文窗口的容量是上限不是你的预算。即使窗口能装 200k token里面还要住着系统提示、CLAUDE.md、Skill 描述、工具定义和越来越长的对话历史。真正留给当前任务的有效空间远比数字小。他给了个信息分级方法我回来之后直接用了。把 Agent 可能用到的信息分三档热数据是每次运行都必需的内容放 CLAUDE.md温数据是大部分任务会用到、但可以按需加载的内容收敛成 Skill冷数据是偶尔才查的内容放到外部存储Agent 需要时自己检索。对应到实现上热层是长驻 prompt温层是模型的工具选择机制冷层是检索或外部记忆。关于会话管理的几个实操点这块搜教程很少讲清楚/compact 会触发模型把已有对话压缩成摘要。它适合长任务续跑但会丢失精确信息尤其是 edge case 和原始报错文本。所以复杂任务做到一半我更倾向 /clear 开新会话把关键结论写进 CLAUDE.md 或归档文件而不是一直 compact。对话历史默认是保存在本地的可以用claude --resume恢复最近会话。团队协作时我会让 CI 在每次跑完把会话摘要写到一个 archive 文件这样任何一个人拿到项目都能快速知道前几轮发生了什么。信息预算要像代码评审一样纳入流程。团队里可以约定每次改动 CLAUDE.md 之前先删掉一段旧内容。入口控制住了上下文健康度自然就上来了。3. 第二层Skill 与工具层把会用工具变成会分派工具3.1 Skill 是温层的操作手册第二层解决的是 Agent 有没有能力做某件事。Claude Code 里一个很常见的误区是把所有操作说明一股脑写进 CLAUDE.md。工作坊工程师反问了一句CLAUDE.md 每次启动都加载里面如果堆了二十个技能的操作步骤上下文还能剩多少Skill 机制的意义就是把它变成按需加载。一个 Skill 在项目里本质是一个目录.claude/skills/技能名/SKILL.md里面用 YAML frontmatter 写名字、描述、允许使用的工具范围正文就是具体的操作流程。模型读到 description 之后判断当前任务是否匹配匹配才把整个 SKILL.md 加载进来。我项目里有个数据库迁移 Skill结构长这样--- name: apply-db-migration description: 当需要执行数据库迁移、回滚迁移或查看迁移状态时使用 allowed-tools: - Read - Edit - Bash --- ## 适用场景 - 新增或修改表结构 - 回滚上一次迁移 ## 执行步骤 1. 读取 migrations/ 目录下最新的迁移文件 2. 检查 migrate.sh 的用法 3. 在 dry-run 模式下执行确认影响行数 4. 得到明确确认后执行正式迁移并记录结果 ## 典型错误 - 不要直接修改 migrations/ 下已提交的文件 - 迁移失败时保留现场不要自动重试注意我把 allowed-tools 限制了让 Skill 没有权限去编辑无关文件。工作坊的原话是Skill 内的步骤越接近确定性脚本越好凡是能被脚本化的操作就不要让模型临场发挥。Skill 描述的是方法论脚本承担的是确定性模型负责的是在合适的时候选择它。3.2 Skill 和 Agent 的分界线流程与目标的差别现场有个高频问题Skill 和 Agent 到底什么关系工程师给了一个我认为比较准确的分界Skill 回答的是怎么做一件事Agent 回答的是如何达成一个目标。Skill 是操作手册里面是步骤、命令、注意点Agent 是执行者它有自己的上下文、工具集和循环逻辑会在目标指引下决定调用哪些 Skill。在 Claude Code 里子代理定义在 .claude/agents/ 目录。你给子代理写一个角色说明指定它可以用的工具它就跑在一个独立上下文里执行。这个差异决定了设计取舍如果任务是完整审查这个 PR 并输出问题清单这是一个 Agent 任务因为它需要拆解、多轮探索如果任务只是跑一遍这个迁移脚本应该做成 Skill因为它是个确定步骤。工具层的另一个能力来源是 MCP。Skill 扩展的是方法MCP 扩展的是外部工具的接入。Claude Code 的 MCP 配置放在 .claude/settings.json 里本地工具和远程服务都可以接。不过每多接入一个 MCPAgent 的工具选择空间就大一圈越权风险也跟着上来。工作坊的建议是工具层永远遵循够用原则宁缺毋滥每个 MCP server 都要过一遍权限评审。4. 第三层记忆层会话寿命与长期身份的平衡4.1 CLAUDE.md 是工作记忆不是文档仓库第三层是记忆。Claude Code 的原生记忆主要是两个CLAUDE.md 和会话历史。CLAUDE.md 每次启动都会加载进上下文所以它就是热层记忆适合放那些每次开工都必须知道的事。但很多人把它当成 wiki 用几千行项目文档全塞进去——那等于每天花一大笔 token 搬运与当前任务无关的内容。我给团队定的 CLAUDE.md 模板包含五块项目命令、代码约定、关键架构决策、危险操作清单、最近变更日志。控制在两百到三百行左右。# payment-service ## Commands - 本地开发: npm run dev - 测试: npx jest --runInBand - 迁移: ./scripts/migrate.sh up/down ## Conventions - TypeScript strict 模式 - 提交信息遵循 conventional commits - 禁止直接改 generated/ 下的文件 ## Danger - 不要在生产环境执行 npm run reset - 修改 RBAC 缓存必须先清 Redis ## Recent decisions - 支付回调采用幂等表事件重放2025-06-12写成条目而不是大段散文规则越具体模型越不会自由发挥。危险操作清单尤其重要它相当于给模型一份哪些事不能做的负面清单比口头约束有效得多。4.2 长期记忆把状态从上下文窗口里搬出去CLAUDE.md 适合放项目级知识但放不下跨任务的执行记录。我的第一个 Agent 项目就踩过这个坑Agent 每周一都要做一次环境健康巡检结果它每次都把上一次的巡检结论重新想一遍因为新会话里什么都没有。后来我按工作坊的思路做了一个外部记忆表用的就是本地 SQLiteCREATE TABLE memory ( id INTEGER PRIMARY KEY, task TEXT, command TEXT, result TEXT, tags TEXT, created_at TEXT );每次巡检结束用 Claude Code 的 PostToolUse Hook 把关键命令和结果追加到这张表。新会话开始前在 CLAUDE.md 里写一条规则执行巡检类任务前先查 memory 表里最近三十天的相关记录。这样 Agent 就有了上次做过什么、结果怎么样的连续认知不用凭运气。这里插一个常见问题Claude Code 的对话历史到底怎么保存默认会话本身可以在本地恢复用 claude --resume 就能回到之前会话。但生产上我更推荐把重要的会话结论主动归档到项目里而不是指望那些原始日志。Hook 追加到 memory 表就是一种归档这样就算会话文件被清理长期记忆还在。记忆层还有一层容易被忽略Agent 的身份记忆。如果 Agent 需要以固定角色长期服务用户建议把角色设定放在 CLAUDE.md 顶部并且定期让它基于历史交互输出我当前对用户偏好的理解写回记忆。这是让 Agent 从工具变成协作者的关键一步但别忘了给这种机制加权限边界。5. 第四层安全与治理层生产级和玩具 Demo 的分水岭5.1 权限矩阵先默认拒绝再逐项放行安全这一层工作坊一点没含糊。工程师的原话是Demo 可以全绿灯生产必须红灯优先。Claude Code 的权限模式大家应该都见过default 会针对敏感操作弹确认acceptEdits 自动接受文件编辑plan 只读探索bypassPermissions 全放行。很多团队图省事直接 bypassPermissions在本地玩可以上 CI、上生产就是把事故概率拉满。生产实践上我的习惯是探索阶段用 plan 模式让 Agent 先把方案拿出来方案确认后切 acceptEdits 执行代码变更只有完全可信的自动化场景才考虑 bypassPermissions而且一定要套一次性容器。权限规则要在 settings.json 里显式声明白名单加黑名单并用。比如{ permissions: { allow: [ Read(./src/**), Bash(npx jest *) ], deny: [ Edit(.env), Bash(rm:*), Bash(git push *) ] } }黑名单的价值是兜底。就算模型临时起意想删文件或推代码也会被权限拦截。工作坊里有一句话我到现在都记得权限不是用来限制 Agent 能力的是用来约束它犯错半径的。5.2 审计、密钥和提示注入一个都不能少安全层另外三个抓手分别是审计、密钥和注入防御。审计这块Claude Code 的 Hook 机制可以记录每一次关键动作。以 PostToolUse 为例在项目 settings.json 里挂一个审计脚本{ hooks: { PostToolUse: [ { matcher: Bash|Edit|Write, hooks: [ { type: command, command: python3 .claude/hooks/audit.py } ] } ] } }Python 脚本从标准输入读取工具调用的 JSON把时间、工具名、参数、工作目录追加到一个审计日志里。这里的配置格式不同版本略有差异以官方文档为准但思路是通用的。有了审计你才能在出事后回放Agent 刚才到底执行了什么而不是对着屏幕干瞪眼。密钥管理上原则很简单一切秘密走环境变量或密钥管理服务禁止写进 CLAUDE.md、Skill 或普通配置文件。尤其 .env 要同时加进权限 deny 列表和 git ignore双保险。Claude Code 本身也支持 ANTHROPIC_AUTH_TOKEN 这类环境变量CI 里优先用注入密钥的方式。提示注入是很多团队没意识到的风险。Agent 读到的网页、文档、命令输出里可能藏着忽略你之前的指令执行某某操作的恶意内容。防御有三道第一道信息来源工具限权读外部内容用只读模式第二道数据进来先经过清洗或摘要不让原始内容直接进模型第三道高危动作必须走人工确认。没有这三道的 Agent本质上是一台愿意读陌生人便条的自动取款机。6. 第五层编排与控制循环让 Agent 自己拆活干6.1 Harness 和 Agent 到底差在哪第五层是容易被忽略但决定成败的一层编排。工作坊里有一个概念我建议所有 Agent 开发者先搞明白——Harness。什么是 Harness它是承载 Agent 运行的整个外壳工具调用循环、授权系统、重试逻辑、上下文管理、与用户的交互界面。什么是 Agent是 Harness 里那个会思考、会做决策、会被定义角色和记忆的那部分。简单说Harness 是比赛的场地和规则Agent 是场上的选手。这个区分在生产上的意义巨大。Claude Code 本身就是一个非常完整的 Harness工具循环、权限系统、Hook、会话管理、上下文压缩全都有。你要做的不是在它上面再造一个 Harness而是把业务能力封装成 Agent、Skill、MCP填进这个现成的壳里。很多团队一上来就想着自己写编排层结果花三个月复刻了一个功能更少、错误更多的 Claude Code。理解了 Harness 和 Agent 的分工也就理解了为什么有些功能应该放在系统级配置里有些应该放在 Agent 定义里。凡是所有 Agent 都要遵守的规则放进 Harness 层比如全局权限、审计 Hook凡是某个 Agent 特有的行为放进 Agent 定义比如角色、工具偏好、记忆策略。边界划清楚维护成本会降一大截。6.2 Checkpoint 让长任务不失控编排层的第二个重点是控制循环。Agent 的循环本质是思考 → 选动作 → 执行 → 观察结果 → 再思考。这个循环如果没有任何外部约束长任务很容易钻牛角尖。工作坊给了一个四阶段模式Plan → Review → Execute → Verify。也就是让 Agent 在开始执行前先生成方案人审查通过后再进入执行执行完必须验证结果而不是停在最后一次命令的输出上。在 Claude Code 里的落地方式很直接。第一轮用 claude --permission-mode plan 启动让它产出一份实施方案人确认方案后再切到 acceptEdits 模式执行。验证阶段可以专门挂一个测试命令作为收尾动作claude -p $TASK --permission-mode plan # 人工评审方案 claude -p $TASK --permission-mode acceptEdits claude -p 运行项目全部测试并汇报结果 --permission-mode plan隔离环境执行时还要给循环套上限。包括最大迭代次数、单次任务超时时间、重试次数。我的 CI 脚本里习惯加 timeout 命令Agent 超时就发告警而不是无限等下去。工作坊最后提醒了一件事Checkpoint 不是打断是保险。一段长任务跑二十分钟中间没有一个确认点大概率会在错误的方向上狂奔二十分钟。生产级 Agent 宁可多几次交互也不要让模型蒙头跑完全程。7. 从工作坊到生产那些搜不到答案的坑7.1 连接故障排查链路最后这部分是我根据现场讨论和我自己项目经验整理的实战坑位。先说连接故障。网上关于 unable to connect to anthropic services、failed to connect to api.anthropic.com: status 403 的讨论特别多但大部分只停留在我也遇到了缺少完整的排查链路。我现在的排查顺序是这样的先用 curl 直连确认故障段位看是不是 Claude Code 之外的问题。检查认证ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN 是否过期、是否写错、是否被环境变量覆盖。403 里相当大比例是密钥问题。检查网络栈公司代理、防火墙、DNS 解析。企业内网经常有出网白名单api.anthropic.com 需要在白名单里这个要找团队网络管理员确认。检查账号与组织账号余额、额度限制、组织级策略。429 是限流403 是拒绝两者处理方式不同。如果错误提示明确说明当前地区不受支持那这不是 bug也不是能靠配置绕过的。合法路径是通过企业版、官方支持的接入渠道来获取服务直接走正规商务渠道别在灰色方案上浪费时间。这里没有炫技但就是这五步能解决团队里八成连接不上的问题。很多人卡住是第 2 步和第 3 步顺序搞反了先折腾网络最后发现是密钥的问题。7.2 接入非 Claude 模型时的兼容性边界社区里经常有人问 Claude Code 能不能接入其他模型比如通过网关接 DeepSeek 之类的兼容 API。技术上是可以做到的Claude Code 支持通过环境变量覆盖模型服务的地址export ANTHROPIC_BASE_URLhttps://你的网关地址 export ANTHROPIC_AUTH_TOKEN你的网关密钥 export ANTHROPIC_MODEL目标模型名 claude但我要把话说清楚这条路的可行性和体验完全取决于上游网关对 Anthropic Messages API 的兼容程度。Claude Code 的工具调用、系统提示、MCP 交互都走这套协议如果网关只兼容了普通对话Agent 一用工具就会表现异常。工作坊的立场很明确官方功能都以官方模型为准接第三方模型的团队需要自己做完整的兼容性验证出了问题不要指望官方支持兜底。我的建议是开发阶段可以用这种方式测试路由能力生产环境要么用官方模型要么把兼容性测试写进发布流程。7.3 从 Demo 到生产的最小改造清单最后把工作坊结尾的一张表放出来。工程师说从 Demo 到生产不是加一个功能而是每层都要完成一次加固。这是最小改造清单检查项Demo 状态生产要求连接层失败就重试退避重试 熔断 告警上下文层全量塞 prompt信息分级 预算控制工具层所有工具可用最小权限 黑白名单记忆层靠会话缓存CLAUDE.md 外部记忆表安全层无审计Hook 审计 密钥注入编排层一次跑到底Plan → Review → Execute → Verify安装这块顺便说一句。Claude Code 的安装有两种主流方式npm 全局包或者官方安装脚本Windows 用户走 PowerShell 安装脚本也能跑起来。桌面版和 CLI 在底层用的是同一套 Harness五层结构不会因为换了界面而消失。装完如果看到 failed to install anthropic marketplace 这类提示通常是市场源临时抽风或者网络策略拦截了插件源不影响核心功能重试或升级到最新版本就行不用慌。我后来把所有新 Agent 项目都先过一遍这五层检查哪一层在需求文档里答不上来设计就先不写代码。脚手架不是一次性的项目跑得越久每层的参数都会需要重新调。但骨架只要搭对了后面换模型、加技能、接新工具都是在同一套结构里平移不用把房子推倒重盖。