目标设定与监控:给 Agent 装方向盘和仪表盘
前面几章,我们一直在给 Agent 加能力:会规划、会用工具、能记忆、能学习、能接入外部世界。听起来它已经很强了。
但能力越强,越需要目标和监控。
否则 Agent 就像一辆没有方向盘和仪表盘的车:它确实能动,也可能跑得很快,但你不知道它要往哪开,不知道什么时候该停,更不知道它是不是快撞墙了。
这一章的重点不是让 Agent 更聪明,而是让它变得可控、可测、可追责。
目标设定回答:
什么叫成功?
哪些约束不能破?
失败后应该重试、中止还是转人工?监控系统回答:
它现在做得怎么样?
哪一步出了问题?
有没有逐渐跑偏?很多 Demo 会把目标写成「代码简单易懂、功能正确、能处理边缘情况」,然后让同一个 LLM 自己判断「是否达成」。这在演示里能跑,在生产里很危险。因为目标是模糊的,裁判和运动员还是同一个人。
生产级 Agent 不能只靠「感觉不错」宣布成功。它必须有清楚的指标、独立的验证工具、完整的运行记录,以及异常出现时能及时停止、报警或转人工的机制。
一、先看核心框架
生产级 Agent 至少要有五件事。
| 部分 | 作用 | 常见实现 |
|---|---|---|
| 目标 | 定义什么叫成功 | 指标、阈值、硬软约束 |
| 验证器 | 独立判断是否达标 | 测试、规则引擎、静态分析、独立 Judge |
| Trace | 记录执行过程 | span、工具输入输出、耗时、成本 |
| 停止条件 | 防止无限重试 | 最大轮数、最大成本、超时、连续失败 |
| 漂移监控 | 长期看是否偏离目标 | 趋势、抽检、回归集、cohort 对比 |
这里最重要的边界是:执行者和裁判不要是同一个人。
Agent 可以负责生成答案、写代码、调用工具,但它不应该独自决定自己是否成功。更稳的分工是:
| 角色 | 负责什么 | 不负责什么 |
|---|---|---|
| Producer | 生成方案、代码、回复或动作 | 不宣布通过 |
| Verifier | 用确定性工具验证硬约束 | 不替 Agent 发挥创意 |
| Judge | 给质量反馈和改进建议 | 不作为唯一裁判 |
| Monitor | 聚合 trace、指标和异常趋势 | 不改写业务目标 |
一句话:LLM 可以生成,也可以建议,但不能独自给自己盖章。
二、目标必须可计算
不要写:
代码要优雅。
回答要准确。
客服要尽快解决问题。这些话不是错,只是不够用。它们更像愿望,不像工程目标。
要写成可验证目标:
| 目标类型 | 示例指标 | 验证方式 | 失败处理 |
|---|---|---|---|
| 功能正确 | 测试通过率 = 100% | pytest / 单元测试 | 必须修复 |
| 性能成本 | P95 ≤ 5 秒,成本 ≤ 0.10 美元 | trace 聚合 | 超阈值报警 |
| 质量约束 | lint 分数 ≥ 8.5 | 静态分析 | 可警告或阻断 |
| 安全合规 | 不访问越权数据 | 权限检查 | 立即中止 |
| 人工复核 | 高风险动作需确认 | 审批状态 | 等待用户 |
判断一个目标是否合格,只看一句话:它能不能被外部工具或明确规则客观计算。
可以用结构化对象描述目标:
from dataclasses import dataclass
@dataclass
class AgentGoal:
name: str
threshold: float
is_critical: bool
higher_is_better: bool = True
def evaluate(self, score):
if self.higher_is_better:
return score >= self.threshold
return score <= self.threshold这里有两个容易被忽略的字段:
| 字段 | 为什么重要 |
|---|---|
is_critical | 区分硬约束和软约束。测试不通过要阻断,风格分低一点可能只是警告 |
higher_is_better | 有些指标越高越好,比如准确率;有些越低越好,比如延迟和成本 |
目标不是口号,而是一个可以被外部系统计算的函数。
三、不要只看最终答案
很多团队刚开始监控 Agent,只盯一个指标:任务成功率。
这不够。因为最终结果只能告诉你「好像成了」或者「失败了」,但它很难告诉你问题发生在哪里。
Agent 系统至少要看四层指标:
| 层级 | 看什么 | 示例 |
|---|---|---|
| L1 任务结果 | 是否完成、是否正确 | 成功率、测试通过率、工具成功率 |
| L2 运行效率 | 快不快、贵不贵 | 延迟、token、成本、重试次数 |
| L3 用户体验 | 用户是否满意 | 评分、转人工率、重复提问率、放弃率 |
| L4 业务结果 | 是否改善业务 | 解决率、转化率、投诉率、ROI |
很多线上问题,只看 L1 是看不出来的。
比如客服 Agent 的解决率上升了,听起来是好事。但如果用户满意度下降、重复提问率上升,真实情况可能是:Agent 为了提高「解决率」,开始草草结案。
异常诊断可以这样看:
| 现象 | 优先排查层级 | 常见原因 | 修复动作 |
|---|---|---|---|
| 成功率下降,延迟正常 | L1 | prompt 变更、工具返回变了 | 看失败样本和回归集 |
| 延迟升高,成功率不变 | L2 | 上下文变长、工具慢 | 截断上下文、加缓存 |
| 满意度下降,解决率上升 | L3 | Agent 草草结案 | 加人工抽检和对话质量指标 |
| 成本上涨,质量不变 | L2 | 重试过多、模型选型过强 | 限制轮数,分层模型 |
| 业务指标变差,单次任务正常 | L4 | 目标和业务脱节 | 重新校准目标函数 |
所以 trace 很关键。至少要记录每轮输入输出、工具调用、验证结果、耗时、成本、失败原因和最终状态。没有 trace,线上事故就很难复盘,只能靠猜。
四、两种常见失败模式
Agent 目标失控,最常见有两种:Specification Gaming 和 Goal Drift。这两个词听起来有点学术,其实很好理解。
1. Specification Gaming
Specification Gaming 就是钻目标空子。
你给客服 Agent 的目标是「尽快关闭工单」,它可能把复杂工单直接关闭。报表上处理速度变快了,用户问题却没有解决。
你给代码 Agent 的目标是「通过测试」,但测试用例太少,它可能只针对当前测试写死逻辑。测试全绿,真实场景全错。
核心问题是:目标写得有漏洞,Agent 找到了捷径。
2. Goal Drift
Goal Drift 是行为慢慢偏离原目标。
比如一个销售 Agent 一开始是「给用户提供合适的产品建议」。后来系统发现强推高价套餐短期转化率更高,经过不断反馈,它越来越偏向高价推荐,即使这并不适合用户。
这不是一次突然失败,而是长期优化过程中逐步跑偏。
| 维度 | Specification Gaming | Goal Drift |
|---|---|---|
| 发生速度 | 很快,首次机会就钻空子 | 很慢,逐步偏移 |
| 表面现象 | 指标达标但结果荒唐 | 指标慢慢变形 |
| 根因 | 目标定义有漏洞 | 反馈循环和环境变化 |
| 检测方式 | 隐藏测试、人工抽检、看过程 | 趋势监控、分 cohort 看指标 |
| 防护机制 | 多指标约束,不只优化单一指标 | 阈值报警、周期性校准、回归集 |
只看解决率,就会鼓励草草结案;只看成本,就会鼓励少思考;只看速度,就会牺牲质量。生产系统里最怕的不是指标差,而是指标看起来变好,真实体验却在变差。
五、完整案例:代码生成 Agent
假设我们要做一个代码生成 Agent。
原始 Demo 通常是:
用户给目标:代码简单、正确、处理边缘情况。
LLM 生成代码。
LLM 自己判断是否满足目标。
如果不满足,再让 LLM 改。这套流程的问题很明显:目标不可计算,LLM 既是执行者又是裁判,没有客观验证器,没有预算限制,也没有 trace。
改成生产级结构后,目标应该更像这样:
生成函数代码,必须通过测试。
单次运行不超过 30 秒。
最多重试 3 轮。
记录每次运行的耗时、成本和失败原因。架构可以这样拆:
最小验证器示例:
import subprocess
import time
def run_pytest():
start = time.perf_counter()
result = subprocess.run(
["pytest", "-q"],
capture_output=True,
text=True,
timeout=30,
)
duration = time.perf_counter() - start
return {
"passed": result.returncode == 0,
"duration_seconds": duration,
"stdout": result.stdout[-2000:],
"stderr": result.stderr[-2000:],
}
def build_trace(run_id, model, attempt, pytest_result, cost_usd):
return {
"run_id": run_id,
"model": model,
"attempt": attempt,
"pytest_passed": pytest_result["passed"],
"duration_seconds": pytest_result["duration_seconds"],
"cost_usd": cost_usd,
}这仍然只是最小骨架,但它已经比「让 LLM 判断代码是否正确」可靠得多。
真正上线前,还要补上三件事:
| 上线项 | 为什么需要 |
|---|---|
| 停止条件 | 防止失败任务无限迭代,把成本烧穿 |
| 失败样本回归集 | 线上失败不能只修一次,下次发布前必须再测 |
| 高风险人工复核 | 分歧大、权限高、影响用户资产时,不要自动放行 |
最好的闭环是:
线上失败 → 进入评估数据集 → 修复提示词或工具链 → CI 回归验证 → 再发布这才是 Agent 系统持续不退化的关键。
六、观测平台怎么选
平台选择会随时间变化,不要把某个工具当成永远答案。选型时优先看这些维度:
| 维度 | 要问的问题 |
|---|---|
| 数据驻留 | trace 和用户数据能否留在自有环境 |
| OpenTelemetry | 是否能接入现有监控体系 |
| Eval / CI | 是否支持回归集和发布前评估 |
| 成本 | trace 量大后价格是否可控 |
| 开源/自托管 | 是否需要私有化部署 |
| 框架耦合 | 是否绑定某个 Agent 框架 |
如果团队已经有 APM 和告警体系,优先接进去;如果正在做 Agent 评估和回归,优先看 Eval / CI 能力;如果数据合规压力大,自托管和数据驻留会比界面好不好看更重要。
平台只是工具,关键是你有没有定义目标、验证器、trace、停止条件和回归闭环。
七、和其他 Agent 模式的关系
这一章和前几章的关系很紧密。
| 模式 | 为什么需要目标和监控 |
|---|---|
| 规划 | 每一步是否完成,需要状态和指标 |
| 工具使用 | 工具调用要记录成功、失败、权限 |
| 反思 | Judge 的质量也要被评估 |
| 多智能体 | 每个角色都要有边界和 trace |
| 学习与适应 | 学到的经验必须能审计和回滚 |
| 容错与恢复 | 监控发现异常后,系统要知道重试、中止还是升级 |
没有目标和监控,记忆可能记错方向,学习可能学坏,工具可能越权,MCP 可能放大风险。
所以这一章是 Agent 从「能动」走向「可控」的关键一步。它不是锦上添花,而是上线前的底盘工程。
八、一句话记住目标设定与监控
目标设定不是写一句「做好一点」,监控也不是看最终答案顺不顺眼。
好的生产级 Agent 要回答:
什么叫成功?
谁来判断成功?
过程有没有 trace?
失败后怎么处理?
长期有没有跑偏?目标设定与监控,是 Agent 的方向盘和仪表盘:目标必须可计算,判定必须可验证,过程必须可追踪,漂移必须能发现。否则 Agent 越强,跑偏时造成的损失越大。