AI代理改坏了才发现?用GitHub Actions在合并前拦截回归

可复现的最小方案是:在拉取请求中部署临时AgentCore测试环境,用固定数据集调用候选代理,等待OpenTelemetry轨迹落入CloudWatch,再执行确定性断言和AgentCore Evaluate API评估。只要脚本把不合格结果转换为非零退出码,并将该工作流设为目标分支的必需状态检查,退化代码就无法直接合并。
不要把合并权交给单个LLM评分。回答的语义正确性可以交给LLM裁判,工具名称、参数结构、禁止调用和调用顺序应优先使用确定性检查;合并结论再综合关键场景、绝对下限和相对基线。这样才能分别发现回答变差、工具选错和多步执行顺序改变。
把完整实现压缩成六个阶段
AWS的GitHub Actions实现 覆盖CDK部署、OAuth保护的MCP服务、代理调用、CloudWatch轨迹采集、内置评估器、阈值判定和资源清理。该实现还指出,CDK返回后Runtime可能仍处于CREATING状态;此时调用会得到424 Failed Dependency,因此测试前必须轮询到READY并预热MCP Runtime。
- 检出PR提交,仅在代理代码、提示词、工具定义、模型配置或相关基础设施发生变化时运行。
- 用CDK部署测试用Agent Runtime、MCP Runtime、Cognito和日志资源,并从部署输出读取ARN、端点及身份参数。
- 轮询两个Runtime的状态,取得机器身份令牌,再按数据集逐条调用候选代理;每个场景使用可追踪的会话标识。
- 等待遥测到达CloudWatch,按会话收集OpenTelemetry spans,确认根轨迹和目标工具调用完整。
- 先执行确定性断言,再调用所需评估器,输出机器可读结果和简短的PR摘要。
- 根据门槛返回成功或失败,并用始终执行的清理步骤销毁测试资源。
遥测超时、缺少span或轨迹截断应标记为基础设施失败,不能当作低质量分数继续计算。失败摘要可包含场景ID、实际工具序列、断言、评估器、分数和解释,但不应把OAuth令牌、敏感工具参数或完整用户内容写入PR评论。
数据集要同时约束答案与工具轨迹

每条记录至少需要场景标识、用户输入、断言和关键等级。事实型任务可增加期望回答或必须满足的事实;工具型任务则增加允许或期望的工具、参数约束、禁止工具和顺序规则。语言、权限角色、可用工具集和测试夹具版本也要固定,否则难以区分代码回归与环境变化。
最小数据结构可包含scenario_id、prompt、assertions、expected_response、expected_trajectory、forbidden_tools、severity和tags。expected_trajectory不必强制精确匹配:必须逐步执行的流程才比较完整顺序;只要求“先检索、后提交”时检查相对次序;允许并行的只读调用则比较工具集合,避免把合法路径判成回归。
用例应覆盖正常路径、权限边界、工具失败、缺少参数和高风险操作。来自生产日志的输入应先脱敏并改造成稳定夹具;依赖库存、时间或外部搜索结果的任务应固定模拟响应,或只校验结构与工具行为,不能把持续变化的文本当作永久真值。
GitHub与MCP需要两层机器身份

第一层身份用于GitHub Actions访问AWS。GitHub的AWS OIDC配置说明 要求工作流授予id-token: write,使凭证操作可以请求OIDC令牌并换取AWS短期凭证;IAM信任策略应同时约束aud和sub,将角色限定到指定仓库、分支或环境。id-token: write本身不授予资源写权限,实际能力仍由所承担角色的IAM策略决定。
第二层身份用于候选代理访问受OAuth保护的MCP服务。无头CI不能完成交互式授权,因此测试环境可使用Cognito的client_credentials流程;但这种M2M令牌只有scope而没有用户角色,并会绕过示例中的角色检查。它能验证代理功能和工具行为,却不能证明用户级授权正确;需要验证角色时,应使用预授权测试账户,或单独对鉴权中间件做确定性测试。
CI角色只应获得部署测试栈、调用测试Runtime、读取对应日志和执行评估所需的权限。来自不受信任fork的代码不应接触客户端密钥,测试MCP后端也应连接沙箱数据或无副作用夹具,而不是生产资源。
用OpenTelemetry spans调用Evaluate API
评估输入不能只有最终回答。OpenTelemetry spans可承载一次会话中的模型交互和工具调用信息,因此调用代理、查询日志与构造评估请求必须沿用同一会话标识。一次Evaluate请求中的sessionSpans只能来自一个会话;混入多个会话会导致验证错误。
Evaluate API参考 说明,该同步接口以OpenTelemetry格式的代理会话spans作为evaluationInput,并为每次调用指定一个评估器;可选的evaluationReferenceInputs可提供assertions、expectedResponse和expectedTrajectory,evaluationTarget则可限定工具调用、单条交互轨迹或整个会话。响应包含数值或类别评分、解释、评估器信息、错误字段和令牌用量。
任务与回答可分别使用GoalSuccessRate和Correctness,工具行为可使用ToolSelectionAccuracy、ToolParameterAccuracy及轨迹顺序评估器。JSON Schema、必需字段、参数范围、禁止工具和严格顺序更适合代码断言或代码型评估器;帮助性、语义正确性和指令遵循再交给LLM裁判。调用脚本既要处理HTTP或权限错误,也要检查evaluationResults中单项返回的错误。
门槛要区分真实退化与评分波动

单一平均分会让大量简单用例稀释一个严重错误。更稳妥的规则是先设置不可豁免的硬门槛:禁止工具被调用、关键参数越界、必需步骤缺失,或高风险场景失败时立即阻断;全部通过后,再汇总回答质量等软指标。
软门槛可同时看三项:每个评估器的绝对最低分、候选提交相对main基线的下降幅度,以及关键标签分组的最低通过率。基线比较必须使用同一数据集、相同测试夹具和相同评估器配置;阈值应根据经过人工复核的历史运行校准,不能直接照搬示例数值。
LLM裁判存在波动时,应固定裁判模型及配置。接近边界的结果可以重复评估或转交维护者复核,但不能无限重试后只保留最高分;一种清晰的策略是硬性检查一票否决,明显跌破软门槛则失败,窄幅灰区则要求人工批准。
把评估结果接到真正的合并闸门
评估脚本最终必须以退出码表达结论,并让GitHub Actions任务在回归时失败;随后把该任务配置为目标分支的必需状态检查。只发布PR评论却保持任务成功,不会形成合并闸门。资源清理还要使用始终执行条件,确保评估失败、调用超时或脚本异常时仍会运行。
启用前可先用已知良好的提交建立基线,再分别制造三类受控退化:删除回答中的关键事实、将正确工具替换为错误工具、调换必须有序的调用。三种变化应触发对应断言或评估器,并在检查结果中指出失败原因。做到这一步,GitHub Actions拦截的就不只是一个偏低的总分,而是可定位到答案、工具或轨迹的代理回归。
订阅我们的新闻通讯
将最新 Web3、AI 和加密货币新闻直接发送到您的邮箱。