做 IaC 交付的同行应该都有同感:一个“加条安全组出站规则”或者“轮换一下证书”的需求,从业务方提单到生产环境生效,经常要等两周甚至更久。不是代码难写,而是整个链路里等的东西太多——等需求确认、等模板评审、等环境就绪、等变更窗口、等验证结果。我这次分享的,就是怎么用四个智能体把这条链路真正压到分钟级。核心底座是 Bedrock AgentCore,智能体之间的工具调用和上下文交换全部走 MCP(模型上下文协议)。整套方案在模拟项目X上跑通后,低风险变更交付时间从平均 19 天降到了 22 分钟,变更失败率也降了一半左右。这篇文章我会完整拆解四个智能体怎么分工、AgentCore 和 MCP 各自解决什么问题、协作链路的关键实现怎么写,以及那些只有真跑过才会碰到的坑。
这篇内容适合正在做 IaC 平台化、DevOps 自动化的团队参考,如果你是刚接触 Agent 开发,也能从中看到一套完整的工程化落地范式,而不是停留在“调用大模型 API 玩一玩”的阶段。
1. 为什么 IaC 交付会卡在“数周”这个量级
1.1 传统交付链路里,时间到底消耗在哪
先看一个典型的 IaC 变更长什么样。某业务团队提了一条需求:给某个微服务的生产环境安全组加一条出站规则,同时把对应的负载均衡器证书换成新签发的。就这么一个需求,传统流程下要走需求拆解、模板编写、代码评审、环境规划、变更审批、生产执行、结果验证七个环节。
我统计过团队的真实数据,一条普通 IaC 变更从提交到生效,平均要 19 天。拆开看:
- 需求澄清与拆解:2~3 天。业务方的描述经常含糊,比如“把证书更新一下”,但没说清是哪个负载均衡、哪个域名、是否涉及多环境同步。
- 环境与模板准备:3~5 天。需要确认现有资源基线、拉取对应模块版本、检查有没有上游依赖变更。
- 代码评审:2~4 天。评审人本身背着好几个并行任务,一条 PR 排队是常态。
- 变更规划与审批:3~5 天。terraform plan 的输出要人工解读,评估影响面,再走变更审批流程。
- 执行与验证:1~2 天。变更窗口通常安排在低峰期,错过一次就再等一天。
这里有个反直觉的事实:真正写代码、执行命令的时间,加起来不到 4 小时。其余全是等待、沟通和人工解读。IaC 交付慢,慢的不是“手”,而是流程里每一站都要排一次队。
1.2 为什么“自动化脚本”解决不了这个问题
有人会问,写个脚本不就行了?比如给 terraform plan 的输出接个定时任务,或者用 CI 模板自动生成代码。这条路我之前也试过,卡在三件事上。
第一,需求到代码的映射是非结构化的。业务需求是自然语言,IaC 代码是结构化声明,中间这层转换依赖语义理解。传统脚本只能做模板填空,遇到“像 A 环境那样加一条规则,但不要开放到公网”这种描述就傻眼。
第二,每个环节的“评审”依赖上下文。评审人要看的不是代码本身,而是代码与现有基线、历史变更、依赖关系之间的差异。脚本可以把 plan 打印出来,但没法像人一样判断“这个变更会不会影响别的服务”。
第三,异常处理是分布式的。plan 报错、状态锁冲突、资源已存在、权限不足,这些异常散落在不同环节,脚本只能逐条写 if-else,写到最后比手搓还累。
所以问题的本质是:IaC 交付是一条需要上下文传递的流水线,以往的自动化手段只解决了某个点上的重复劳动,没有解决整条线的上下文接力。
1.3 四个智能体“接力跑”的思路
我的方案是把这条流水线切成四段,每一段由一个带独立上下文和工具的智能体负责,Agent 之间通过统一状态对象进行交接。
- Agent-1 负责需求解析,把自然语言变成结构化的变更意图。
- Agent-2 负责代码生成,基于组织模板库和基线数据生成 IaC 代码。
- Agent-3 负责审查与规划,理解 plan 输出并做风险评估。
- Agent-4 负责执行与验证,把变更落到具体环境并校验结果。
四个 Agent 不是四个孤立工具,而是共享同一个“任务上下文”的分工单元。上游 Agent 的输出会成为下游 Agent 的输入,任何一个 Agent 发现自己搞不定,就把任务连同半成品状态回传给上一个 Agent。这个协作模式,是这套方案从“自动化”走向“智能体化”的关键。
2. 技术底座选型:Bedrock AgentCore 与 MCP 的组合逻辑
2.1 AgentCore 到底解决了什么问题
先澄清一个容易混淆的点:Bedrock AgentCore 不是一个“模型”,也不是一个现成的“Agent”,而是一个把 Agent 从开发到运行的生命周期托管服务。它负责回答这几个问题:
- Agent 的会话状态放哪、怎么持久化?
- Agent 怎么决定调用哪个工具、以什么参数调用?
- Agent 跑挂了怎么重试、怎么恢复上下文?
- 多个 Agent 之间怎么共享记忆、怎么避免状态冲突?
这些问题如果不使用托管服务,就得自己造轮子,而且是非常难的轮子。我在自研阶段写过一版简陋的 Agent 运行时,很快被三个问题击穿:会话状态在并发场景下互相覆盖、工具调用失败后上下文丢失、Agent 内部“跑偏”后没法追溯。AgentCore 把这些问题收敛成了配置项,我只需要声明 Agent 的行为边界和可用工具集,运行时的调度、重试、会话管理都由它兜底。
另外一个很重要的点:AgentCore 对多智能体协作有原生支持。每个 Agent 实例有独立的会话上下文,同时可以订阅共享的“任务事件总线”,这样 Agent 之间传递的不是松散的文本,而是结构化的任务状态变更事件。这个能力让我省掉了自建消息队列的活儿。
2.2 MCP 把工具能力做成了“即插即用”
MCP——模型上下文协议,是这套架构里另一块关键拼图。它的价值可以类比成电子设备的 USB-C 接口:以前每个设备要专门的线,现在只要都支持同一个标准协议,一条线通吃。
在 IaC 场景里,Agent 需要触达的工具和数据源非常多:模块仓库、模板库、terraform CLI、云平台 API、审批系统、监控平台。如果没有统一协议,每个工具都要给 Agent 写一套专用适配层,而且是按“某个模型”定制的适配层——换个模型就废了。MCP 把工具封装成标准的“工具服务器”,Agent 通过协议发现工具、读取工具的输入输出 schema、发起调用。工具和模型完全解耦。
我在这套方案里一共起了 5 个 MCP 服务器节点:
- 模板库服务器:提供组织级 IaC 模块的检索、版本、依赖信息。
- 基线服务器:提供目标环境的现有资源清单和配置基线。
- 执行服务器:封装 terraform init/plan/apply 等命令,以沙箱方式执行。
- 验证服务器:对接云平台 API 做资源级验证和状态检查。
- 审批服务器:把变更单推送给人工审批通道,并回传审批结果。
这 5 个节点各自独立部署,Agent 需要哪个能力就“插上”哪个。后续要加新工具,比如加一个多云账号登记系统,只需要再起一个新的 MCP 服务器,Agent 侧零改动。这一点在长期维护中的价值,比刚开始选型时预想的还要大。
2.3 为什么不用纯自研编排
不少同行第一反应是:我自己写个状态机 + 调用模型 API,不是更可控?我对比过两条路,最终选 AgentCore + MCP,核心原因是三个维度。
| 维度 | 自研编排 | AgentCore + MCP |
|---|---|---|
| 会话与状态管理 | 需自建存储与并发控制 | 托管,自带持久化与隔离 |
| 工具接入 | 每个工具写适配层,绑定模型 | 统一 MCP 协议,即插即用 |
| 多 Agent 协作 | 需自研消息传递机制 | 原生支持,事件总线 |
| 可观测性 | 需自建日志与追溯 | 内置“思考轨迹”与工具调用记录 |
| 迭代速度 | 新能力开发周期长 | 新工具只需按 MCP 规范暴露 |
自研的天花板更高,但那是给“研究 Agent 本身”的团队准备的。我的目标是快速解决 IaC 交付问题,不是重新发明 Agent 框架,所以选择把框架层的复杂度交给托管服务,把精力集中在四个智能体的业务逻辑上。
3. 四个智能体的职责拆解
3.1 Agent-1 需求解析器:从自然语言到变更意图
Agent-1 是整个链路的入口,它读的是需求单、工单或 PR 描述,输出是结构化的“变更意图”。这个意图对象长这样:
{ "change_intent": "update_security_group_rule", "target": { "environment": "production", "resource": "sg-app-backend", "region": "ap-southeast-1" }, "actions": [ {"op": "add_rule", "direction": "egress", "port": 443}, {"op": "update_certificate", "target": "lb-public-web"} ], "constraints": { "no_public_exposure": true, "change_window": "low_peak" } }这个环节的难点不是“读懂”,而是“读不准的时候怎么处理”。业务方写的“把证书更新一下”,到底是全量替换还是追加?影响的服务列表要不要同步更新?Agent-1 内置了一套澄清策略:当置信度低于阈值时,不瞎猜,而是生成多选一的澄清问题,通过审批服务器推给需求方确认。实测大概 30% 的需求会触发澄清,宁可多一轮交互,也不要带着错误意图往下走。
我还给 Agent-1 加了“意图校验清单”,比如“生产环境变更是否带 change_window”“是否声明了 no_public_exposure”这类必填项。意图对象如果缺关键字段,Agent-1 会直接把单子退回去,绝不让不完整的意图流入下游。
3.2 Agent-2 代码生成器:模板之上做“组合”而不是“重写”
Agent-2 拿到变更意图后,先通过模板库服务器的 MCP 接口检索匹配的 IaC 模块。比如要加安全组规则,它会优先找到组织里已有的 sg 模块,而不是从零写一段 resource 定义。这个设计有意为之:组织级的 IaC 规范、命名约定、标签策略都沉淀在模板里,Agent 的组合优先级是“先找模板,再定制参数,最后才考虑新增资源”。
这样有两个实际好处:一是代码风格天然统一,不会出现一个 Agent 写的代码和团队其他人写的对不上;二是评审负担小,评审人看到的大部分内容是熟悉的模块引用,只需要关注参数差异。
Agent-2 的另一个职责是处理“环境差异”。同一个变更,在开发环境和生产环境的参数往往不同,比如实例规格、副本数、CIDR 段。它会读基线服务器返回的环境差异表,把差异参数按环境注入到生成的代码里,避免“开发环境没问题、生产环境 CIDR 冲突”的经典事故。
生成完代码后,Agent-2 还会跑一遍本地的基础校验,比如 terraform fmt 和 terraform validate,确保交给下游的不是一份连语法都不对的代码。
3.3 Agent-3 审查与规划器:像资深评审人一样读 plan
Agent-3 是我花最多时间调的一个,因为它负责的是整条链路里最需要“经验”的部分:读 terraform plan。
核心流程是:Agent-2 生成代码后,Agent-3 拉取代码,通过执行服务器跑一遍 terraform plan,然后解析 plan 输出,生成一份“变更影响评估”。这份评估包含三块内容:
- 变更范围:新增、修改、删除的资源列表,特别标出“删除”类操作。
- 风险分级:根据资源属性变化判断是低风险(加个 tag)、中风险(改配置参数)还是高风险(重建实例、删资源、改网络策略)。
- 依赖影响:通过基线数据判断变更会波及哪些上下游资源。
这里有个关键细节:Agent-3 不是让大模型“读一行 plan 文本”就给出结论,而是先把 plan 的 JSON 输出转成结构化事件,再交给模型分析。纯文本解读的准确率大概只有 75%,结构化之后能到 95% 以上。
我在 Agent-3 的提示词里还嵌了一套“评审规则”,比如“任何 destroy 操作必须至少标记为中风险”“实例类型变更必须检查是否触发重建”“涉及公网暴露的规则变更必须附加安全提示”。这些规则优先于模型自由判断,相当于给模型套了一层安全护栏。
3.4 Agent-4 执行与验证器:最后的闸门
Agent-4 是唯一的“手”,负责真正执行 apply,也是安全闸门的最后一环。默认策略是:低风险变更自动执行,中风险变更需要人工一键确认,高风险变更直接挂起,生成完整的风险评估报告交给变更委员会人工决策。
执行完成后,Agent-4 不会只看 apply 的 exit code 就结束,它会走验证服务器的 MCP 接口,对变更后的资源做真实验证。比如新增了一条安全组规则,它会调云平台 API 查这条规则是否真实存在、源地址段是否和预期一致;更新了证书,它会去检查证书是否在有效期内、是否已关联到正确的监听器。
这个“验证闭环”是压降变更失败率的关键。以前人工验证经常漏掉“规则加上了但顺序不对”这种细节,Agent-4 把验证项变成了可枚举的检查断言,漏检率大幅下降。
4. 核心实现:Agent 协作链路与关键代码
4.1 MCP 工具服务器的设计范式
每个 MCP 服务器本质上就是一组工具定义的集合。以“执行服务器”为例,看一个工具是怎么定义的。MCP 的工具定义是 JSON Schema 风格:
{ "name": "run_terraform_plan", "description": "在指定环境的沙箱目录内执行 terraform plan,返回结构化解析结果", "inputSchema": { "type": "object", "properties": { "environment": {"type": "string", "enum": ["dev", "staging", "production"]}, "working_dir": {"type": "string"}, "extra_vars": {"type": "object"} }, "required": ["environment", "working_dir"] } }工具实现里最需要注意的是“返回值的结构化程度”。很多人写 MCP 工具,直接把 CLI 的 stdout 原样返回给 Agent,这是错的。Agent 需要的是结构化数据,不是一坨带颜色转义符的终端文本。我在 run_terraform_plan 里做了解析包装,把 plan 输出转成 JSON:
{ "summary": {"add": 2, "change": 1, "destroy": 0}, "resources": [ { "address": "aws_security_group_rule.egress_443", "action": "add", "risk_level": "low", "reason": "新增出站规则,不影响存量资源" } ], "validate_errors": [] }这个结构的价值在 Agent-3 上体现得很明显:模型拿到的是“机器可读的结论 + 人类可读的解释”,而不是一堆需要二次解析的原始文本。
每个 MCP 服务器我都是独立进程部署,通过本地 socket 和 Agent 通信。好处是工具进程崩了不影响 Agent 主进程,Agent 检测到工具不可用时可以直接走“降级到人工处理”的路径。
4.2 Agent 之间的状态传递:共享意图对象的“接力棒”
四个 Agent 之间怎么交接任务?我的做法是所有 Agent 共用同一个“任务意图对象”,每个 Agent 在自己负责的阶段往里填内容。整个状态机的流转可以概括为:
解析阶段: human_request -> change_intent 生成阶段: change_intent -> iac_code + module_refs 规划阶段: iac_code -> plan_report + risk_assessment 执行阶段: plan_report -> apply_result + verification_report在 AgentCore 里,我通过“任务事件总线”把每个阶段的状态变更通知给下游 Agent。Agent 不需要主动轮询,而是订阅自己关心的事件类型。比如 Agent-3 订阅了“代码生成完成”事件,事件负载里带着代码产物地址和变更意图对象引用。
有个细节必须强调:Agent 之间传递的不能是“自然语言总结”,必须是结构化对象。我之前犯过的错是让 Agent-1“写一段话”传给 Agent-2,结果 Agent-2 每次都从自然语言里重新猜一遍意图,准确率直线下降。改成结构化对象后,交接损耗基本为零。用一句话概括:Agent 之间的沟通越像“API 调用”,越不像“人传话”,系统越稳。
4.3 安全边界:把人工审批从“流程前置”改成“风险触发”
很多人担心引入 Agent 自动化后,安全审批没了。我的做法正好相反:审批不仅保留了,而且比原来更精准。
- 原来的审批是“前置审批”,不管变更大小,先排队等人看,导致低风险变更也被卡两三天。
- 现在的审批是“风险触发审批”,低风险的直接走,高风险的自动生成材料并挂起等人工。
这个转变依赖 Agent-3 的风险分级准确率。我针对这个指标做了专门调优,比如“delete 操作必须至少中风险”“change 了实例类型必须标记为重建风险”等规则优先于模型判断,保证高风险动作不会被模型误判为低风险。这个“规则优先、模型兜底”的混合策略,是 Agent 系统落地的安全压舱石。
审批环节本身也走 MCP:Agent-4 需要人工确认时,通过审批服务器的 MCP 工具创建一条审批任务,人工在现有审批系统里点一下按钮,结果再通过 MCP 回传给 Agent。这样 Agent 完全融入了企业已有的合规流程,而不是另起炉灶。
5. 落地效果与量化分析
5.1 交付时间:从 19 天到 22 分钟的账
| 环节 | 人工流程耗时 | 智能体流程耗时 |
|---|---|---|
| 需求解析与澄清 | 2~3 天 | 15~30 分钟 |
| 代码生成 | 1~2 天 | 3~8 分钟 |
| 评审与规划 | 2~4 天 | 2~5 分钟 |
| 审批(含人工门禁) | 3~5 天 | 低风险 0,高风险 1~2 天 |
| 执行与验证 | 1~2 天 | 3~6 分钟 |
取中位数,低风险变更从 19 天降到 22 分钟,其中大头是 Agent-4 执行后的资源验证时间。高风险变更虽然最终仍需人工审批,但因为前置的解析、生成、规划已经全部自动化,审批人拿到的是一份“已经充分验证过的风险报告”,决策时间也从原来的几个工作日压缩到小时级。
整个统计周期覆盖了 200+ 条真实变更请求(模拟项目X),低风险变更占比约 70%,这也是整体平均耗时被大幅拉低的原因。
5.2 质量指标:失败率和回滚率的变化
时间只是一个维度的收益,质量才是长期更值钱的。改造前的基线数据:变更失败率(apply 失败或验证不通过)约 12%,因此触发的回滚率约 5%。改造后 200+ 条变更的统计结果:
- 变更失败率降到 6%,主要失败原因集中在环境权限和账号租户配置问题上,与 Agent 逻辑本身无关。
- 回滚率降到 2%,且回滚全部由 Agent-4 的“变更前快照 + 自动逆向 apply”机制完成。
- 人工评审发现的“带病变更”比例从 9% 降到 2%,说明 Agent-3 的风险评估能力已经覆盖了绝大多数人工评审的关注点。
需要说明的是,这些数字来自一个基础设施相对标准化的环境。如果你的环境里大量资源是历史遗留的“一次性代码”,Agent 的理解成本会高很多,指标可能没那么好看。
5.3 适用边界:不是所有 IaC 都适合 Agent 化
必须泼一盆冷水:这个方案有自己的适用边界。以下几类场景不建议硬上:
- 首次大规模上云、资源从零创建的项目。这类任务的“上下文”极度依赖业务架构决策,Agent 生成代码反而容易产出“技术上正确、架构上错误”的产物。
- 强合规审计、要求每一步都有人工签字的行业流程。风险触发式审批在监管严格的行业可能过不了审计。
- 高度定制的内部自研 IaC 引擎,连成熟生态都没有,Agent 的工具链成本会远大于收益。
最适合的是“增量变更密集”的中大型环境:每天都有大量小的安全组调整、配置更新、证书轮换、实例规格变更。这类环境里,Agent 化收益最大。
6. 常见问题与排查技巧实录
6.1 Agent 上下文污染:上游的错误结论被下游“洗白”
跑起来之后遇到的第一个大坑,是上下文污染。具体表现是:Agent-1 对一个模糊需求做了错误假设,但这个错误假设在传给 Agent-2 和 Agent-3 之后,不但没有被发现,反而被后续 Agent 当成既定事实继续推演,最终生成一份“逻辑自洽但意图错误”的 IaC 代码。
排查办法:我加了一条硬性审计规则——每个 Agent 的输出必须包含“assumptions”字段,列出自己在推导过程中做过的假设。下游 Agent 如果发现假设与自己的判断冲突,必须回传“澄清请求”,而不是将错就错。
6.2 MCP 工具超时与重试风暴
工具调用的超时问题也很典型。terraform plan 在资源多的大环境里可能跑 5 分钟,而 MCP 调用默认超时只有 60 秒。超时后 Agent 会重试,重试又会排队,最终把执行服务器压垮。
解决方案是分级超时配置:读操作(模板查询、基线读取)设 30 秒;写操作(plan、apply)设 10 分钟;同时给每个工具声明“幂等性”标签,只有幂等工具才允许自动重试。terraform apply 不是幂等的,所以它超时后只能挂起等人工介入,绝不能盲目重试。
6.3 Plan 与 Apply 不一致:状态文件漂移
有一次 Agent 反复出现“plan 显示 0 变更,但 apply 时资源冲突”的诡异问题。最后发现是状态文件漂移:某个资源被人在控制台手动改过,terraform 状态文件没同步,导致 plan 读到的愿境界和真实愿境界不一致。
解决办法是在 Agent-3 的规划阶段增加 refresh 步骤,强制在 plan 之前先执行 terraform refresh 同步真实状态;同时对“控制台手动变更”这种操作做了专项检测:如果状态文件里的更新时间戳与资源真实变更时间差超过阈值,就中止流程并提示人工确认。
6.4 权限模型:Agent 用的凭证比人还大
这是最容易被忽略的安全隐患。给 Agent 配置执行凭证时,一开始图省事给了管理员权限,结果 Agent 在错误意图驱动下差点删掉一个不该删的资源组。
教训:Agent 的权限必须遵循最小权限原则,并且和人工操作的权限完全隔离。我给 Agent 专门建了一个只读加有限写权限的专用身份,只允许操作预定义的资源前缀和标签范围内的对象。任何超出范围的写操作直接返回权限错误,而不是报给模型去“想办法绕过”。这一点一定要写进架构文档里。
6.5 回滚不是删掉重来:逆向 apply 比快照恢复更稳
Agent-4 的回滚逻辑,最开始我用的是“变更前打快照,出问题恢复快照”,结果发现快照恢复在大规模网络变更场景下非常慢,而且会把无关的并发变更也一起回滚掉。
后来改成“逆向 apply”方案:每次变更前,Agent-3 额外生成一份“反向变更计划”,也就是把这次变更的 diff 反过来生成一个回滚 plan。出问题时,Agent-4 直接执行反向 plan,只撤销本次变更的影响,不影响其他资源。代价是每次变更要多跑一次反向 plan 生成,但换来的是回滚的精准性和速度,这笔账非常划算。
6.6 可观测性:Agent 系统必须能“复盘对话”
Agent 系统跑久了,一定会遇到“这单子为什么这么处理”的追问。如果只有最终结果没有过程,排查起来会非常痛苦。AgentCore 内置的思考轨迹和工具调用记录解决了一部分问题,但我在工程侧还额外加了两个东西。
一个是“变更档案”,每条变更从需求原文到最终执行结果,所有中间产物(意图对象、生成代码、plan 报告、验证断言)全部归档到一个对象存储里。出问题就翻档案,看是哪一步产生了偏差。
另一个是“对比回放”,出问题时可以把实际执行链路和同场景的成功链路做对比,快速定位差异在哪。这个功能帮我在一次“Agent 突然开始给所有资源加 tag”的异常里,五分钟内找到了原因——某次模板库更新引入了一个新默认参数,Agent-2 把这个参数当成了必填项。
这套系统从最初的想法到稳定运行,前后迭代了三轮。我最深的体会是:Agent 系统落地的难点从来不在“模型能不能听懂话”,而在“工程上能不能防住模型的错”。MCP 把工具接入标准化了,AgentCore 把运行时的脏活累活接管了,但真正决定这套方案能不能用的,还是那些审计字段、分级超时、权限隔离、逆向回滚的工程细节。如果你也想做类似的实践,我的建议是先从最痛的一个环节切入,比如只做 Agent-3 的“plan 自动风险评估”,跑通验证好了再扩展成完整链路,一步到位的方案往往最难落地。