2923 字
约 9 分钟
17
S21-X18 · Agent 的协议、执行模式与评测口径:A2A、Twelve-Factor 与四类污染

S21-X18 · Agent 的协议、执行模式与评测口径:A2A、Twelve-Factor 与四类污染

Agent 项目最容易在两个地方翻车:协作——两个 Agent 靠自然语言传话,接口一变就全线崩;评测——同一份测试集被反复调参,分数不再代表能力。前者要协议,后者要口径。这篇把协议层(Agent2Agent)、授权层(OAuth2.0)、交付规范(Twelve-Factor)、生成式脚手架与五种执行模式、七个评测指标串成一条链。


1. Agent2Agent:协议先定"谁暴露什么"

A2A(Agent2Agent)的核心不是"让两个模型聊天",而是把 Agent 当服务描述:可发现的描述(agent card,声明能力与端点)、任务(task)的生命周期、产出物(artifact)。这三个词定下来,跨团队对接才有落脚点。

{
  "name": "invoice-auditor",
  "description": "校验发票字段与金额一致性",
  "url": "https://agents.internal/invoice-auditor",
  "version": "1.4.0",
  "capabilities": { "streaming": true, "pushNotifications": false },
  "skills": [
    { "id": "audit", "inputModes": ["text/plain", "application/json"],
      "outputModes": ["application/json"] }
  ],
  "authentication": { "schemes": ["Bearer"] }
}
概念 作用 不定清楚会怎样
agent card 能力与端点的声明 调用方只能靠文档口口相传,版本漂移即失效
task 一次有状态的工作单元 难以中断、恢复、追进度
artifact 任务的产出物 结果只能塞在文本里,难以结构化校验
message 交互的消息载体 上下文丢了就只能整段重发
streaming / push 长任务的通知方式 长任务只能轮询,成本高

任务状态机要显式定义,不要用自然语言描述"处理中":

submitted → working → (input-required → working)* → completed | failed | canceled

input-required 这一档最容易被省掉,省掉之后所有"需要人补一句"的场景都只能靠重跑。


2. OAuth2.0:Agent 的身份不是"用户的密码"

Agent 访问工具与数据时,权限模型通常是 OAuth2.0 的两种形态:client credentials(以 Agent 自身身份访问自有资源)与授权码/令牌交换(代表用户行事,需用户授权与 scope 收敛)。

形态 谁授权 scope 粒度 适用
client credentials 平台自己 服务级 Agent 访问自有 API、内部知识库
授权码 + PKCE 终端用户 用户级 + 细粒度 scope Agent 代用户读邮件、改日程
令牌交换 上游令牌换下游令牌 降权(scope 收窄) 多服务串联,避免全权令牌扩散
服务账号 运维配置 粗 批处理任务
$ curl -s -X POST https://auth.internal/oauth2/token \
    -d grant_type=client_credentials \
    -d client_id=invoice-auditor \
    -d client_secret="$SECRET" \
    -d scope="invoice.read invoice.write"

三条纪律:令牌不落日志、scope 按最小集申请、调用前校验 scope 而非调完再报错。Agent 的自主循环会放大权限问题:一次误授权,循环里可能被调用上百次(典型量级)。


3. Twelve-Factor:哪些因子对 Agent 服务仍然成立

Twelve-Factor(12-Factor App)是服务化时代的交付规范。Agent 服务在"进程模型"和"状态"上偏离得最多,其余因子基本照用。

因子 在 Agent 服务里 是否仍成立
代码库 + 依赖显式声明 模型权重、提示词、工具 schema 都要进版本 成立,但要扩展到"非代码资产"
配置与代码分离 模型名、温度、超时、预算都是配置 成立
后端服务视为附加资源 模型 API、向量库、沙箱都是可替换资源 成立
构建/发布/运行分离 提示词变更也是发布 成立,需纳入发布流程
进程无状态 会话、记忆必须外置 成立,但"外置"成本高
端口绑定 自托管 Agent 需暴露服务端口 成立
并发靠进程模型扩展 长任务要能中断与重入 部分成立,需补任务队列
可丢弃性 进程被杀不丢任务 要靠任务状态机落实
环境等价 开发/生产的模型版本必须一致 最容易破的一条
日志作为事件流 每次工具调用都是事件 成立
管理进程一次性 索引重建、评测跑批 成立
管理进程与常驻进程同源 评测脚本与线上代码同仓库 成立

最常破的是"环境等价":本地小模型调试、线上大模型,提示词两边表现完全不同。把模型版本写进配置并纳入发布审计,比事后排查便宜得多。


4. Services-as-Software 与生成式脚手架:GPT-Engineer 一类工具的边界

"服务即软件"(Services-as-Software)把能力做成可被调用的服务单元,而不是可下载的程序。这个视角对 Agent 很贴切:价值在编排已有服务,而不是重写它们。

生成式脚手架(GPT-Engineer 是早期代表,AutoGPT(Significant-Gravitas 组织维护)把"自主循环"走得更远)解决的是"从一句需求到可运行骨架"。产出特征是:

产出 可用性 需要补什么
目录结构与入口文件 高 依赖版本、构建脚本
数据模型与接口雏形 中 校验、错误码、幂等
测试骨架 低 断言、边界用例、数据构造
部署配置 低 资源限制、健康检查、密钥注入

把这类工具当"第一次提交的作者"而不是"交付者":骨架进仓库,然后按 Twelve-Factor 补齐配置、状态、可观测。跳过这一步,脚手架带来的速度会在第一次线上故障时全部还回去。


5. 五种执行模式:Single-Task、Self-Feeding、Multi-Level、Step-Back、Self-Reflection

模式 结构 解决的问题 代价
Single-Task 一问一答,无循环 简单确定性任务 复杂任务一次做不完
Self-Feeding 上一步输出喂给下一步,循环直到收敛 迭代式改进(写作、重构) 会放大错误,需要停机条件
Multi-Level 分层:规划层 → 执行层 → 校验层 长任务分解、职责隔离 层间协议成本,调试链变长
Step-Back 先抽象出原则,再回到具体问题 细节淹没时的方向修正 多一次调用,可能答非所问
Self-Reflection 产出后自我批判并修订 格式错误、遗漏约束 容易自我肯定,需要外部校验
Self-Feeding 的停机条件(必须显式写):
  1) 连续两轮 diff 为空
  2) 达到最大轮次 max_rounds
  3) 校验器通过
  4) 预算耗尽
任一满足即停;没有停机条件的循环等于无限循环。

Step-Back 与 Self-Reflection 常被混用,方向不同:前者向上抽象(这条规则适用哪些情况),后者向内检查(这次输出违反哪条约束)。前者治跑偏,后者治格式与遗漏。

Multi-Level 的关键是层间协议结构化,别用自然语言传"我觉得应该……"。规划层输出任务列表(JSON),执行层逐条返回状态,校验层只判定不改写。


6. 评测口径:七个指标与四类污染的对应关系

评测最容易出的不是"分数低",而是"分数不可信"。七个指标各自防一种失效:

指标 定义 防的是哪种失效
Outcome-based 只看最终任务是否达成,不看中间步骤 步骤漂亮但结果错
Per-test-case 每个用例独立计分,不跨用例汇总 一个用例的运气拉平均分
Cross-contamination 测试用例之间是否互相泄漏信息 前一题的答案出现在后一题
Cross-user 不同用户/会话的数据是否隔离 上下文串味、隐私泄漏
Relevance_Score 检索或回答与问题的相关度 答得通顺但不切题
Final_Score 加权后的总分 单一指标被过度优化
Delta-Based 与基线版本的差值,而非绝对值 不同批次不可比
{
  "run_id": "eval-20261109-03",
  "model": "qwen3-4b",
  "mode": "outcome_based",
  "cases": [
    { "case_id": "c-017", "passed": true,  "relevance": 0.86, "delta_vs_baseline": 0.04 },
    { "case_id": "c-018", "passed": false, "relevance": 0.41, "delta_vs_baseline": -0.22,
      "failure": "missing_field", "artifact": "out/c-018.json" }
  ],
  "final_score": 0.74,
  "contamination_check": { "cross_contamination": 0, "cross_user_leak": 0 }
}

四类污染的落地做法:

1) Cross-contamination:每个用例在独立上下文里跑,禁用历史缓存;
2) Cross-user:评测数据按用户分片,禁止跨用户共享检索索引;
3) 记忆污染:评测前清空长期记忆,或用只读快照;
4) 提示词污染:被测提示词与评测脚本同版本,禁止评测中途改配置。

Delta-Based 最被低估:绝对分数会随测试集难度漂移,只有同一测试集、同一基线、同一模型版本下的差值才可比。所以每次评测要落 run_id、模型版本、提示词哈希、测试集版本四元组。


7. 排错:六个"跑通了但不可信"的现象

现象 原因 处理
分数突然大涨 测试集被用于调参 换留出集,重跑基线
同一 run 两次结果不同 温度不为 0、并发顺序不定 固定种子与执行顺序
用例答案互相引用 上下文共享了缓存 每用例独立上下文
多用户数据串味 索引未按用户分片 加命名空间或按用户隔离
任务卡死不返回 Self-Feeding 缺停机条件 加轮次上限与预算闸门
协议升级后全量失败 card 版本与实现不一致 版本号纳入契约测试

8. 边界:什么时候不该再加 Agent

场景 为什么 Agent 不合适 该用什么
固定流程、输入格式稳定 自主性带来不确定性,收益为负 确定性流水线
强合规审计 每步都要可复现 规则引擎 + 人工签核
延迟敏感(毫秒级) 多轮调用满足不了 单次小模型或缓存
需要精确计算 模型不做算术保证 工具调用 + 代码执行
评测样本极少 区分不出模型差异 先攒数据再选型

一句话:协议定能不能对接,模式定跑不跑得完,口径定分数算不算数。


10. 自测

  1. A2A 里没有 agent card,对接会退化成什么状态?
  2. 服务凭证模式与授权码模式,scope 粒度差在哪里?
  3. Twelve-Factor 里哪一条在 Agent 服务上最容易被破坏?
  4. Self-Feeding 的停机条件至少要写几条,分别是哪几条?
  5. Step-Back 与 Self-Reflection 的方向差别是什么?
  6. 为什么 Delta-Based 分数比绝对分数更可信?
S21-X18 · Agent 的协议、执行模式与评测口径:A2A、Twelve-Factor 与四类污染
https://www.clxhxhhr.top/posts/6015/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。