Agent 开发实战(八):可观测性与评估——上线前必须做的几件事

Moryu 4 阅读 agent

Agent 开发实战(八):可观测性与评估——上线前必须做的几件事

前面七篇让 Agent 能跑、能查、能聊、能协作。但一旦真实使用,你会立刻遇到三个问题:它刚才为什么答错?这次花了多少钱?我改了代码会不会把效果改坏?本篇讲可观测性(看得见)评估(量得准)——这是 Agent 从"能跑"到"敢用"的最后一关。

1. 为什么非做不可

Agent 是"非确定性系统":同样的提问,两次可能走不同工具路径、花不同 token。没有观测和评估,你:

  • 出了错只能靠用户反馈,被动;
  • 算不清成本,预算失控;
  • 迭代没有基准,改 A 坏 B 发现不了。

2. 结构化日志:每次请求留痕

structlog 输出机器可读日志,关键字段一次打全:

import structlog, time, uuid
log = structlog.get_logger()

def run_agent_obs(question):
    trace_id = str(uuid.uuid4())[:8]
    start = time.time()
    usage_total = {"prompt":0, "completion":0}
    log.info("agent.start", trace_id=trace_id, question=question[:80])

    # …Agent 循环内,每次 LLM 调用后:
    # usage_total["prompt"] += resp.usage.prompt_tokens
    # usage_total["completion"] += resp.usage.completion_tokens
    # log.info("llm.call", trace_id=trace_id, tools=[c.function.name for c in msg.tool_calls])

    log.info("agent.done", trace_id=trace_id,
             cost_tokens=usage_total, latency_ms=int((time.time()-start)*1000))
    return answer

这样一次提问在日志里是一条完整链路:开始 → 每次工具调用 → 结束(含 token 与耗时)。排查时按 trace_id 一搜就全出来。

3. 全链路追踪(进阶)

工具多、链路长时,上 OpenTelemetry 把"一次 Agent 运行"做成 trace,工具调用作为 span 嵌套。但先用好结构化日志,日志够用就别急着上 OTel——过度基建也是成本。

4. 成本监控

按模型单价把 token 换算成钱,累计到 Redis/数据库,做日/周报表:

PRICE = {"gpt-4o-mini": {"in":0.00015,"out":0.0006}}  # 每 1K token 美元,按实际填

def cost(model, prompt_t, completion_t):
    p = PRICE.get(model, {})
    return (prompt_t/1000)*p.get("in",0) + (completion_t/1000)*p.get("out",0)

配合告警:单日成本超阈值邮件提醒。很多"Agent 跑飞了"第一时间是从账单发现的——主动监控能早半天上车。

5. 评估:用固定问题集 + 评分

别靠感觉判断"改完是不是更好了"。建一个 eval 集:20~50 个真实问题 + 预期(答案应包含的关键事实 / 不应出现的错误)。

EVAL_SET = [
    {"q":"上周各渠道首单转化率?", "must_include":["自然流量","微信投放"], "must_not":["凭空"]},
    {"q":"sample1.vcf.gz 的变异类型分布?", "must_include":["missense_variant"], "must_not":[]},
]

def run_eval():
    for case in EVAL_SET:
        ans = run_agent(case["q"])
        ok = all(k in ans for k in case["must_include"]) \
             and not any(b in ans for b in case["must_not"])
        print(f"{'✅' if ok else '❌'} {case['q']}")

LLM-as-Judge(进阶)

对"质量"类问题(是否清晰、是否有依据),可让另一个模型按 rubric 打分(0~5)。注意:

  • 评判模型与被评模型分开,避免"自己夸自己";
  • 评分只作参考,关键事实类仍用 must_include 硬校验;
  • 评测集要随业务更新,别一成不变。

6. 回归测试

把 eval 集做成 CI 的一环:每次改 Agent 代码,跑一遍 eval,分数掉太多就拦截合并。这能救你无数次"我以为改好了"。

# .github/workflows/eval.yml 示意
- run: pytest tests/eval_agent.py   # 内部调用 run_eval 并断言通过率 >= 基线

7. 一个最小可落地的观测清单

  • 每次请求有 trace_id,日志含问题、工具调用序列、token、耗时
  • token 按模型换算成成本并累计
  • 固定 eval 集 + 硬校验(must_include / must_not)
  • eval 接入 CI,防回归
  • 成本/错误率超阈值告警

8. 小结

可观测性和评估不是"锦上添花",是 Agent 上线的前置条件

  • 日志让你"看得见"每一次决策链路;
  • 成本监控让你"算得清"钱花哪了;
  • eval 集让你"量得准"改了好还是坏了。

做到这三层,你才真正敢把这个 Agent 交给用户、也敢持续迭代它。

Agent 最难管理的不是模型,是它的不确定性。把不确定性变成可观测、可度量的东西,它就可控了。