58天78个Agent的部署中,6768次失败输出全部返回HTTP 200。真正问题在于边界校验缺失——模型返回格式不符合下游parser预期,如字段缺失、语言错误、阶段答案错配等。
一次成功的 HTTP 响应不代表一次成功的 Agent 运行。
一份来自 58 天部署 78 个 Agent 的实践者报告显示,共记录了 6,768 次输出失败。失败原因不是传输层面的错误:每一次都返回了 HTTP 200,长度合理,看起来也流畅。最昂贵的失败案例甚至平淡无奇——都是形态不匹配:缺少必填字段、语言错误、包含禁用词,或者给出了错误阶段的答案。
对于任何正在构建编码 Agent、评审 Agent 或无人值守自动化系统的人来说,这是一个值得警醒的案例:
将模型输出视为不可信数据。在边界处校验契约,确保下游阶段能够安全消费。
本文将这一观察转化成一个可复现的小型故障实验场。
你应该能复现的那类故障
想象一个评审阶段,其下游解析器期望一条判定行:
action: approve
模型可能返回了一条内容详尽的评审意见,但判定被埋没在正文里。人工审批通过了,解析器却失败了。
传输层是绿的。模型调用是绿的。整个工作流断了。
同一类故障还出现在以下场景:
这些都不是首先要换成更大模型的理由。它们是让边界可观测、可 enforcement 的理由。
构建契约网关
先用确定性检查,不让 LLM 去评判另一个 LLM 的输出。
def validate_review(text: str) -> list[str]:
errors = []
if len(text.strip()) < 150:
errors.append('too_short')
if not any(line.startswith('判定:') or line.startswith('判定:')
for line in text.splitlines()):
errors.append('missing_required_verdict')
forbidden = ['お客様の声', '顧客の声']
if any(term in text for term in forbidden):
errors.append('forbidden_phrase')
if not any('。' in line for line in text.splitlines()):
errors.append('expected_language_missing')
return errors
errors = validate_review(model_output)
if errors:
record_rejected_output(errors, model_output)
stop_downstream_dispatch()
else:
publish_to_next_stage(model_output)
重要的不是那段日语检查的具体逻辑。换成你的系统实际需要的契约即可:必填标题、schema 类型、仓库路径、测试名称、引用字段,或有限的行为列表。
网关应该返回结构化的证据,而不是只返回 true 或 false:
action: reject
reasons:
- missing_required_verdict
- forbidden_phrase
contract_version: review-v3
artifact_id: art_01J...
这让故障变得可修复,而不是变成一块绿色仪表盘——上面显示正常但交付物实际上缺失了。
记录原因,不只是记录结果
一个常见的反模式是只存储布尔值,比如 contract_satisfied = false。这会摧毁调试 drift 所需的全部信息。
不要静默丢弃被拒绝的输出。应用保留和脱敏规则,但保留足够的证据来回答:产生了什么、哪个契约拒绝了它、后续阶段有没有读取过它?
这和我用于审计就绪型 Agent 日志的证据规范是同一套思路:一条"运行完成"的事件,远不如一条记录了检查项和产物明细的记录来得有力。
增加产物溯源检查
一种出人意料的故障模式是:上游阶段运行正常,但输出从未被使用。对这一点要做显式测试。
给每个产生的产物一个稳定 ID。
要求消费方记录输入产物的 ID。
拒绝一个声称成功但没有消耗输入 ID 的阶段。
在一段时间窗口内对比产出数量和消费数量。
即便每个进程心跳都是绿的,也对不断扩大的缺口发出告警。
这能捕获那些输出质量检查根本无法察觉的连线 bug。
在信任一个新的 Agent 工作流之前,注入每一种情况并验证预期的证据:
最后一种情况涉及副作用。契约网关保护的是输出形态;它不能证明外部行为是否真实发生。将执行证据和出站投递证据分开保留。
一个常驻运行时可以让调度器、worker 和证据写入器保持就绪,但托管基础设施并不定义你的输出契约,也不能让一个绿色的 HTTP 响应变得有意义。如果你需要为无人值守的 OpenClaw 工作负载托管基础设施,Ampere 上的托管 OpenClaw 托管是一个可以考虑的选项。但验证、凭证作用域、prompt 注入防御和对账仍然是你自己的责任。
实用检查清单
在发布一个 Agent 阶段之前,确认以下事项:
问题不是"模型回答了吗?"而是"一个版本化的、可观测的契约是否接受了一个下一阶段实际消费的产物?"
这就是"活的 Agent"和"运转的工作流"之间的区别。
如果你在构建 AI Agent 或开发者工具,欢迎关注我,我会持续分享实用的故障实验室和可复现的边界控制测试——而不是能力演示。