AI Agent生产级可观测性体系建设:从Trace到评估全链路指南
2026/9/6 5:49:30 网站建设 项目流程

1. 为什么生产级 Agent 仍是黑盒:先搞清楚诊断难点在哪

AI Agent 这个概念从 2025 年开始就彻底火出圈了,各种团队都在做,从 Copilot 式的单轮工具调用,到 Planner-Executor 式的多步骤任务编排,再到 Multi-Agent 的协作系统。但我观察到的一个核心问题是:绝大多数团队在开发环境里觉得 Agent "能用",一上生产就抓瞎——因为它是一个典型的不透明系统,出问题了根本不知道去哪看。

一个 Agent 请求从进入到完成,中间可能经历这些环节:意图识别、任务规划、工具选择、工具参数生成、工具结果解析、上下文改写、多轮反思、记忆读写,偶尔还有 Agent 间的消息传递。任何一个环节出错,或者任何一个环节变慢,都会直接影响用户体验。比如用户说"帮我查一下上个月的销售数据,然后生成一份图表报告",系统先调 CRM 接口拿数据,再调数据分析工具做聚合,最后调图表生成服务出图。这个链路里如果图表长宽比不对,你怎么知道是数据查询阶段就出了问题,还是图表服务自身的 bug?

传统 Web 服务的监控思路在这里会失效大半。一个常规的 Spring Boot 接口,你可以看 QPS、RT、错误率,按接口维度打点,日志里打上 traceId,慢查询一抓一个准。但 Agent 的逻辑不在你的代码里——它在模型返回的 token 序列里。模型为什么选了 A 工具而不是 B 工具?为什么第三次调用时突然放弃了这个任务?这些决策过程的"为什么",在传统监控体系里根本无迹可寻。

这正是我写这篇东西的动机:团队如果打算把 Agent 推向生产环境,可观测性不是一个可选项,而是基础设施。而且它不能是事后补的,必须在架构阶段就纳入设计。本文将围绕一个生产级 Agent 的可观测性体系怎么建,拆开讲讲设计与落地的完整思路。

一个合格的 Agent 可观测性体系,至少要能回答下面这几类问题:

  1. 发生了什么:用户发了什么,Agent 接收到的完整输入是什么,每一步决策的上下文是什么。
  2. 为什么这么做:模型为什么会选择某个工具、为什么输出某个参数、为什么中途换策略。
  3. 结果怎么样:工具是否执行成功,返回内容是否被正确解析,最终答案是否满足需求。
  4. 花了多大代价:token 消耗、延迟分布、成本估算——这可是生产环境每天都要算的账。
  5. 行为是否漂移:同一个问题,今天是这个处理逻辑,明天是不是就变了?模型升级之后行为变化有多大?

这五个问题,传统监控体系最多只能给你第 3 项的残缺答案,其余全要靠猜。所以,下面我按照从底层到上层的思路,把整条链路的设计逐一展开。

2. 全链路观测的四层结构:从 Trace 到 Evaluation 缺一不可

要建一个不黑的 Agent 系统,我把它拆成四个层次,每一层解决一类问题,且彼此之间有数据依赖关系。你可以把它理解成给 Agent 做"体检"——Trace 层看每次请求具体做了什么,就像心电图;Metrics 层看整体的健康趋势,就像体温曲线;Logs/Events 层看每次决策的原始证据,就像病历;Evaluation 层判断行为对不对,就像医生最终的诊断结论。

2.1 L1:追踪层——按 Agent 执行逻辑重定义 Trace 语义

传统 Trace 是按服务调用来组织的,一个请求打到 API Gateway,依次经过 Service A、Service B、Service C,形成一条带有层级关系的调用链。Agent 场景的 Trace 结构完全不同,需要把语义重定义清楚。

一个典型的 Agent Trace 长这样:

  • Trace:对应用户的一次完整请求,这是链路追踪的统一 ID。它从用户输入进入系统开始,到最终回答返回给用户为止。
  • Span:一个 Agent 生命周期里的一次"动作",例如一次 LLM 调用(LLM Span)、一次工具调用(Tool Span)、一次记忆读取(VectorDB Span)、一次内部推理过程(Agent Span)。
  • Parent-Child 关系:LLM 调用是 Agent Span 的子 Span,工具调用结果解析后的下一轮 LLM 调用又是前一个 Agent Span 的子 Span,由此构成多叉树而不是单一的线性链。

以 OpenTelemetry 生态为例,我建议这样映射:

Agent 中的概念OTel 语义关键属性
用户请求Traceuser_id, session_id, agent_version
Agent 主循环Root Spanagent_id, task_type, model_name
LLM 调用Span (type=llm)model, prompt_tokens, completion_tokens, temperature, cost
工具执行Span (type=tool)tool_name, args_json, result_summary, error_type
记忆读写Span (type=vector_db)collection, top_k, similarity_scores
Agent 间通信Span (type=agent_msg)from_agent, to_agent, msg_type

这里面有几个特别容易被忽略的字段,我单独拿出来强调。model_name 必须打上标签,因为生产环境一定会做模型灰度,同一个应用里会有两个版本的模型在跑,没有这个字段你没法对比。temperature 这类采样参数也值得记录——很多人排查"为什么今天的回答风格变了"时,最后发现是配置中心把 temperature 从 0.2 改成了 0.8。tool args_json 尤为重要,这是 Agent 最常出错的地方,你排查的所有工具调用问题,没有原始参数你就只能盲猜。

2.2 L2:指标层——用北极星指标加护栏指标管理 Agent 健康度

追踪层解决的是"单次请求到底发生了什么"的问题,但单条排查在系统运行平稳时,效率太低了。指标层负责把 Trace 数据聚合出有意义的统计信号。

我给生产 Agent 建设的指标分三类:

第一类:北极星指标

  • 任务完成率:Agent 在多少次对话中达到了用户的最终目标,而不是仅仅"回答了"。这个指标需要用 LLM-as-a-Judge 或业务埋点来判断,无法从日志里直接算出来。记下这个定义——很多团队在这里偷懒,用"无异常回答率"替代,结果指标好看但业务不满意。
  • 有效轮次:用户和 Agent 完成一个目标花费的对话轮次。目标设定为 5 轮以内,超过的视为效率低下。

第二类:护栏指标

  • 单轮 token 消耗 P50/P95:超过设定阈值说明 Agent 在无意义地循环,大概率陷入了反思死循环。
  • 工具调用失败率:尤其是同一工具连续失败 N 次后 Agent 是否仍坚持调用——这是最常见的 Agent 缺陷模式。
  • 上下文窗口占用率:多轮对话后占用率超过 80% 时,Agent 的糟糕表现可能并非"笨",而是上下文快满了导致注意力分散。
  • 单请求最大时间:有些 Agent 会出现死循环式的自调用,实测中最长见过一个请求跑 40 多分钟还不结束。

第三类:成本指标

  • 模型调用费用估算:按 token 单价乘以用量,按天聚合成成本曲线。如果单位成本突然暴涨,大概率是 agent 行为异常导致多轮循环,这时候要能追溯到具体的 trace 样本。
  • 缓存命中率:语义缓存命中率低说明你的用户请求过于分散,考虑调整缓存策略。

这些指标从哪来?我不建议单独自研一套,直接在 L1 层的 Trace 导出器(Exporter)里写一个 Metrics 插件,在 Span 结束事件里做增量聚合,打到 Prometheus。后面我会给一个具体的代码示例。

2.3 L3:日志与事件层——记录 token 级决策证据而非应用日志

传统日志系统里你记的是"调用了什么服务,返回了什么状态码"。Agent 的日志完全不同,它要记录的是模型决策过程的证据。这在排查问题时是决定性的:

  • 第 2 轮 LLM 调用的完整 prompt 是什么?有没有关键信息被截断?
  • 模型第 3 次返回的 tool_calls 参数里,tool_name 是"search_docs"但传入的 query 是本该在第四轮才用到的信息,说明上下文组织出现了顺序错乱。
  • 第 5 轮模型输出了 final_answer,但前面某次工具返回的 JSON 被截断了,导致最终答案残缺——从最终答案上根本看不出原因,只能回看日志里的工具结果解析片段。

所以,在 L3 层我的建议是:每个 Span 对应一份结构化事件日志,使用 JSON Lines 格式写入对象存储,长期保留。字段可以包括:trace_id、span_id、parent_span_id、event_type、event_data、时间戳。event_data 可以很大——整个 prompt 可能包含几千个 token,几 MB 的数据都属正常——所以这部分不适合进通用日志系统,对象存储更好。

但要注意:event_data里可能包含用户个人信息(PII)。生产环境的日志清洗策略必须提前定好,建议在记录前做一次脱敏处理,替换邮箱、手机号、地址等敏感字段,否则日志审计这一关就过不去。

2.4 L4:评估层——行为质量评估与回归测试自动化的基石

评估层是整个可观测性体系里我花费精力最多也认为回报最大的一层。传统的"正确/错误"二元评估对 Agent 不适用——你必须引入多维度的评分体系。我在生产环境用了一套五维评分模型:

评估维度说明评分方式
工具选择准确率Agent 是否在应该用搜索时用了搜索LLM-as-a-Judge + 规则校验
参数生成正确率给工具传的参数是否类型、语义都对规则校验 + 人工抽检
任务完成度最终回答是否满足用户需求LLM-as-a-Judge
效率得分是否用了超过必要的轮次和 token规则计算 + 基准对比
安全合规得分是否触发了拒绝服务、是否泄露敏感信息规则 + 分类器

这个评估结果一方面直接回写到指标层,作为北极星指标的数据来源;另一方面沉淀为测试集,回归测试时自动跑一遍,看更新后的系统是否在新样本上表现更强。没有这一层,你说的"我改进了系统""我提高了准确率"都是没有证据的。

3. 落地实操:OpenTelemetry 埋点 + Langfuse 可视化 + 数据管道清洗

理论讲完了,下面进入实操环节。这里我讲一套可以照着做的技术栈组合,并附带核心代码骨架。

3.1 埋点方案:为什么我选定 OpenTelemetry GenAI 语义规范

选型之前我对比过几条路线:纯自研 SDK、阿里云 ARMS 的 LLM 链路追踪、LangSmith、Langfuse、OpenTelemetry。最终我的结论是:如果你要做一个持续演进、多个 Agent 子系统共享的生产级平台,OpenTelemetry 是底座的唯一理性选择。

原因有几点。第一,厂商中立。你不会被某一家云厂商或某个框架绑定死。今天你的 Agent 基于 LangChain 写的,明天可能切成自研的,SDK 不用换。第二,生态兼容。Langfuse、LangSmith 等商业化平台都支持 OTLP 协议导入,你的数据既可以自建链路,也能平滑接入商业工具。第三,规范在快速演进。OTel 社区已经有 GenAI 语义约定(Semantic Conventions for Generative AI),对 LLM、VectorDB 等 Span 类型做了标准定义。现在接入进去,等于提前卡位。

具体埋点我分两段来看。如果你用的是 LangChain/LlamaIndex,直接用官方集成的 OpenInference 或 Traceloop SDK,它会自动把每个 callback 事件映射成 OTel Span。如果你用的是自研 Agent 框架,那就要手动埋点,核心代码长这样:

import json import time import uuid from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanExporter from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.trace.export import SimpleSpanProcessor tracer_provider = TracerProvider() tracer = trace.get_tracer("agent-tracer") def start_llm_span(parent_context, model_name, operation, prompt): context = trace.set_span_in_context(parent_context) span = tracer.start_span( name=f"llm.{operation}", context=context, kind=trace.SpanKind.CLIENT ) span.set_attribute("gen_ai.operation.name", operation) span.set_attribute("gen_ai.request.model", model_name) span.set_attribute("gen_ai.prompt", prompt[:2000]) # 截断存储 return span def end_llm_span(span, response, token_usage): span.set_attribute("gen_ai.response.completion", response[:500]) span.set_attribute("gen_ai.usage.prompt_tokens", token_usage.get("prompt_tokens", 0)) span.set_attribute("gen_ai.usage.completion_tokens", token_usage.get("completion_tokens", 0)) span.set_attribute("gen_ai.usage.cost_usd", estimate_cost(token_usage)) span.end() def start_tool_span(parent_context, tool_name, tool_args): context = trace.set_span_in_context(parent_context) span = tracer.start_span( name=f"tool.{tool_name}", context=context, kind=trace.SpanKind.INTERNAL ) span.set_attribute("agent.tool.name", tool_name) span.set_attribute("agent.tool.args", json.dumps(tool_args, ensure_ascii=False)) return span

这段代码骨架看起来简单,但我在实际项目中踩了几个坑,值得拿出来说:

坑一:必须在同一进程内传递 Context。Agent 循环如果用了异步任务、消息队列、线程池,Context 没有通过trace.set_span_in_context显式传递,子 Span 就会丢失父母关系。整条链路看起来就是一堆孤立的 Span,毫无意义。

坑二:Prompt 不能无脑全量记录。一个几千 token 的 prompt,你每次调用都记全量,存储成本会飞速增长。我建议建一个采样策略——P95 延迟的请求全量记录,P50 的按 10% 比例采样,只有异常的请求记录完整 prompt。

坑三:工具参数和结果必须设置大小上限。工具返回的 JSON 有时候会到几 MB。策略是:元数据(tool_name、status、耗时)全量记录,内容字段只保留前 N 个字符。需要看完整内容时,通过 trace_id 去日志系统查原文。

3.2 可视化与检索:不要自研 UI,交给 Langfuse 这类平台

可观测性体系如果只有数据没有可视化界面,等于白做。我试过在 Grafana 里强行展示,体验非常差,因为 Agent Trace 的多叉树结构和调用时间线,Grafana 的默认面板根本展示不了。

我的做法是:数据采集走 OTel,展示层接 Langfuse。Langfuse 的价值不只是 UI,它的 Trace 视图对 Agent 场景做了专用优化,你可以看到每一次 LLM 调用的完整输入输出、工具执行的时间线、token 消耗。如果团队感觉后者的成本可接受,这是目前投入产出比最高的一条路。

Langfuse 支持 OTLP 导入,接入流程不复杂:

# 自托管 Langfuse docker run -d --name langfuse \\ -e DATABASE_URL=postgresql://user:pass@host:5432/langfuse \\ -e ENCRYPTION_KEY=your-encryption-key \\ -p 3000:3000 \\ langfuse/langfuse:latest # 配置 OTel SDK 将 Span 导出到 Langfuse 的 OTLP 端点 export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer sk-lf-xxx"

这里有一个关键点:Langfuse 的 Trace 结构基于 LANGCHAIN 等框架的 trace 树,如果你的 Agent 是自己写的、没有走 LangChain,你仍然可以通过 OTel SDK 上报标准 Span。Langfuse 内部会有个映射层,把 OTel 的 Span 嵌套关系转成它自己的 Trace 时间线。我在实践中发现,工具调用的 Span 层级映射偶有错位,需要查一下它当前版本的parent_span_id映射逻辑,必要时在后处理脚本里做一次父子关系修复。踩过的坑,提前给你们打预防针。

3.3 数据管道:从 Trace 到指标到评估的全链路流动

有了埋点和可视化之后,还有一道关键工序:把原始 Trace 数据华为可消费的指标和评估结果。这块我设计成一个标准的数据管道,避免在业务代码里写死。

管道流程分成四步:

  1. OTel Collector 从应用侧接收 Trace 数据。
  2. Collector 里配一个 OTLP 导出器,一份落到 Kafka,一份落到对象存储作为原始存档。
  3. 消费 Kafka 的数据进入 Flink 或 Spark 流式计算,聚合出 L2 层的指标,写入 Prometheus / VictoriaMetrics。
  4. 同一份数据进入评估服务,调用 LLM-as-a-Judge 模型跑评分,结果写回 PostgreSQL,供业务报表和回归测试使用。

这个架构的收益是:业务侧只负责埋点,后续一切的聚合、清洗、评估都是异步的,完全不影响主流程的时延。

这里需要注意,采集 Agent 的 Trace 数据时要处理好成本问题。LLM 的 token 费用不能完全靠 Trace 里的 usage 字段做——因为 Agent 内部可能还有缓存命中的调用,usage 字段可能为 0。所以成本统计要以 Gateway 层(模型网关)的账单数据为准,Trace 里的 usage 只是辅助。

4. 核心难点拆解:Agent 的"命令树"与工具调用链怎么做可观测

很多团队做 Agent 可观测时,最大的困惑是:Trace 画出来了,数据也有了,但不知道怎么从茫茫 Trace 森林里快速定位问题。这部分要说的是 Agent 特有的两个难点——命令树结构和工具调用链——以及怎么把它们变成可观测的对象。

4.1 把 Agent 的执行过程建模成一棵命令树

我在设计系统时,让 Agent 在执行每一步之前先声明一个"当前目标",这个目标在 Trace 上就是一个子 Span。比如用户请求"帮我安排周五的项目会议,并通知参会人",Agent 内部可能会形成这样的命令树:

task: organize_meeting ├── span: discover_participants (调用联系人服务) ├── span: check_conflicts (调用日历服务) ├── span: send_invitations (调用邮件服务) │ ├── span: get_email_templates │ └── span: send_email_via_smtp └── span: confirm_meeting (调用会议服务)

命令树的价值在于:它可以做结构化的模式识别。比如你发现在某一天,所有失败请求的命令树都多了一个分支——多调用了一次redis_read_memory。这就说明最近的 Agent 逻辑里,记忆模块的读取路径改了,可能引入了多余步骤。没有命令树,这些规律几乎不可能从平铺的 Span 列表里找出来。

具体落地时,我会在 Span 的agent.command.path属性里用一个点分路径表示层级:task.organize_meeting.discover_participants.contact_service。这个字段可以直接被 Prometheus 聚合、被 ClickHouse 做 LIKE 查询,排查问题时很好用。

这里需要关注的是:Agent 的执行路径是动态的,不是固定模板。同一个任务,用户多问一句"顺便把会议纪要模板也准备好",命令树就会多出一整条分支。所以可观测性系统要能支持对新分支的自动发现——我的做法是把命令路径写入标签后,在 Grafana 里按agent.command.path维度聚类,一段时间后自动就能看到高频分支。

4.2 工具调用链的因果分析表:让"异常"可解释

Agent 最容易被吐槽的是"不可解释"。用户问"你为什么做了这个操作",产品没法回答。而如果我们在工具调用的每个环节记录好因果证据,这个问题就能转化为一份可查询的因果分析表。

我设计的工具调用因果表包含以下核心字段:

字段示例值说明
trace_idt_20260913120304_ab12关联到完整链路
agent_state_ids_03f9Agent 当前的状态 ID
trigger_eventthink: need_stock_price触发本次调用的决策事件
tool_nameget_stock_price实际调用的工具
args{"symbol": "AAPL"}完整参数
tool_effectsuccess/error/timeout执行效果
result_impactcaused_retry, altered_plan结果对后续决策的影响
reversed_agent_actionnext_plan_step: 3可反推的下一步

这套表建好之后,"为什么 Agent 最终给出一个错误答案"就变成一个可以回答的问题:因为某个工具调用返回了残缺的 JSON,result_impact被标记为altered_plan,Agent 接下来的决策基于错误数据,最终答案自然错。整个链条的每一步都有据可查。

这里我额外提一个重要实践:对工具调用的结果做摘要。工具返回的原始数据可能是一个几千行的数组,但 Agent 真正重要的是摘要(比如"共返回 42 条记录,前 3 条是...")。我建议在工具返回环节做一次摘要嵌入,既降低了日志的存储压力,也在因果表里直接显示可读的关键信息,排查效率能提升不少。

4.3 幂等性与重试风暴:很常见的"隐形杀手"

生产环境里我遇到过一个特别能暴露 Agent 可观测问题的场景——工具调用超时后的自动重试。Agent 框架一般会配置重试逻辑,工具超时后会换参数再试。但现实情况是,某些外部接口不具备幂等性(比如"创建订单"接口),重试会导致重复下单。

这种情况下,可观测性体系需要做到两点:

  1. 对工具调用的"幂等性等级"打标:在 Trace 的 Span 属性里标记tool.idempotency: idempotentnon_idempotent。遇到non_idempotent工具的重试,指标层要单独打一个tool.non_idempotent_retry_total计数器。
  2. 对 Agent 状态快照做定期持久化:每次工具调用前后的 Agent 内部状态(当前计划、已收集的信息、未完成的目标)都要有快照。这样一旦出现重试风暴,你可以从快照里精确定位到"它为什么觉得需要重试"。

这两点做进去之后,我再也没有出现过"我知道它重试了,但不知道它为什么重试"的困境。

5. 从可观测到可评估:建立 Agent 的回归测试与质量打分闭环

可观测性体系做到第四层(评估层)的时候,天然会和另一个重要话题产生交集:Agent 的回归测试。因为如果你已经能对单次 Agent 运行自动评分,那你就能够把大量历史数据变成测试集,做自动化回归。这块我在实际生产中获得的价值,比可观性本身还要大。

5.1 利用线上 Trace 构建"准黄金数据集"

传统测试集是人工构造的,你写 50 条测试用例,期望 Agent 能跑对。但 Agent 系统的状态空间太大了,50 条根本不够,而人工构造的过程本身又会引入主观偏见。我对这个问题的解法是:从线上 Trace 自动挖掘数据

具体做法是,让评估模块对线上的每条 Trace 做自动评分,然后按评分分层:

  • 高分段(专家级):多轮逻辑清晰,工具选择准确,作为"黄金数据"进入测试集。
  • 中分段(普通):有一定参考价值,定期抽检后筛选补充。
  • 低分段(失败样例):保留为负面测试集,验证新版本是否修复了已知问题。

这套机制跑起来之后,你的回归测试集是活的,它会随着系统的运行自动增加覆盖度。我在实际生产环境中,一个季度就把测试集从手工的 80 条扩充到了 3 万多条,覆盖了大量真实用户路径。这种量级的覆盖,是传统手工测试根本达不到的。

5.2 多维评分加权的实战配置

自动评分的核心是一个可配置的多维评分体系。我之前提到过五维评分模型,落地时具体配置如下:

evaluation: metrics: tool_accuracy: weight: 0.3 judge: llm-as-judge threshold: pass_score: 80 param_correctness: weight: 0.2 judge: rule_based threshold: pass_score: 90 task_completion: weight: 0.3 judge: llm-as-judge threshold: pass_score: 75 efficiency: weight: 0.1 judge: rule_based threshold: max_rounds: 8 max_tokens: 4000 safety: weight: 0.1 judge: classifier threshold: blocklist_hits: 0 grade_thresholds: good: 85 ok: 70 bad: 0

tool_accuracy你可能会问,llm-as-judge的评分到底可靠吗?我的经验答案是:可靠,但要选对 judge 模型和评分 prompt。不要贪便宜用 7B 的本地模型做 judge,它自己都可能判断错。我建议 judge 模型至少和 Agent 模型同代或更高一档。另外,评分 prompt 里要给 judge 模型提供上下文——"工具 A 应该被调用的原因是 xxx,实际调用的是工具 B"——它才能做出有依据的判断。

5.3 让评估结果反哺开发闭环

评估不只是给个分就完了,更关键地是形成开发闭环。我的团队在开发流程中建了这样的自动化动作:

  • 每次 PR 提交 Agent 提示词或工具定义的改动,自动跑一遍线上挖掘出来的黄金测试集,对比新旧版本的评分差异。分数下降的模块直接标记,PR 仪表盘上会亮红。
  • CTC(分类-测试-修正)循环:每次线上出现失败样例,自动进入测试集,并在下个迭代中跟踪修正结果。实测表明,这个循环持续运转,系统的问题数会在几周内明显收敛。
  • 版本对比报告:模型升级(比如从 GPT-4o 换到新版本),用同一测试集跑新旧两个版本的评分分布。你就能给出一个可量化的结论:新版在工具选择准确率上提升了 5 个百分点,但在任务完成度上下降了 2 个百分点。

这套闭环跑起来之后,"提升 Agent 质量"就不再是一件凭感觉的事,每次改动都有数字支撑。

6. 与研发流程融合:Agent 可观测性不是运维的事

最后这块我想讲一个观点:Agent 的可观测性体系如果只定位成"运维基础设施",一定会失败。它是整个研发流程的一部分,从需求评审到发布上线都牵涉其中。而且它与 CI/CD 的结合往往被严重低估。

6.1 CI 流水线的接入:把质量评分变成卡点

我们团队的发布流水线里加了一个硬性门槛:任何 Agent 逻辑的改动,如果跑不过黄金测试集里对应模块的评分阈值,不能合并。具体来说:

  1. 开发者在分支上提交代码(往往是提示词、工具定义或 Agent 编排逻辑的改动)。
  2. CI 运行 Agent 回归测试集,跑完自动输出评分对比表。
  3. 如果task_completion低于上一个版本的 95% 或绝对分数低于 70 分,流水线直接失败。
  4. 如果测试集覆盖不足(比如本轮改动涉及的工具调用路径在测试集里没有样本),流水线会提示补充 case 才能通过。

这个卡点一开始遭到团队反对,觉得拖慢节奏。但跑了一个月后反对声消失了,因为大家发现:以前线上事故要到用户侧才知道,然后花半天排查;现在改动上去之前,测试集会主动暴露大部分问题。

6.2 产品视角:给非技术角色一个"可观测"的窗口

可观测体系如果只有技术指标,产品经理和运营团队就很难介入 Agent 的质量管理。我建议给非技术角色留一块"行为审计看板",展示这样一些内容:

  • 每个用户会话的 Agent 决策时间线(不含敏感信息)。
  • 用户对每个回答的"有帮助/无帮助"反馈,和系统的自评分做一个对照。
  • 高频失败的对话主题,按用户问题聚类。

产品团队有了这个窗口,能直接发现"用户反复问同一个问题,但 Agent 就是答不对"这一类体验问题,并能给出具体例子反馈给研发团队。这个看板看起来简单,但它带来的跨团队协作效率提升非常明显。

6.3 组织层面:谁为 Agent 的行为质量负责

这最后一条经验可能有点"软",但我觉得重要。传统服务的质量责任很清晰——后端团队对接口负责,前端团队对页面负责。Agent 的行为质量是跨层的,它取决于提示词、模型选择、工具接口、上下文管理、评测标准,横跨算法、工程、产品、数据。

我们的做法是建一个Agent 质量虚拟小组,每周用可观测性数据开一次复盘会:哪些 Trace 是低分的、为什么低分、归因到哪层、哪一层需要改动。归因责任表是这样的:

Trace 异常类型可能根因责任团队
工具选择错误提示词指令不清晰 / 工具描述冲突算法/产品
LLM 高延迟模型网关配置 / 模型版本回归平台工程
上下文超限记忆策略缺陷 / 历史消息压缩不足算法
评分与用户反馈背离评估标准问题算法/产品

这个虚拟小组不一定是常设的,但当体系建立后,每次 TLS 分析都有明确的 R 位,出问题不会再出现"模型"和"代码"相互甩锅的情况。

到这里,可观测性体系从底层埋点到上层评估再到嵌入研发流程的完整思路就全部铺开了。最后我补充一点个人体会:做 Agent 可观测,不要贪大求全,先把"命令树 + 工具因果表 + LLM 采样日志"这最核心的三板斧落地,再逐步把指标、评估、CI 卡点接上去。我见过不少团队一上来就想做全面的 LLM 评测平台,结果数据采集质量一塌糊涂,评估模型也是应付了事,最后系统反而变成了新的黑盒。先跑通一个端到端的简单闭环,看到它真实地帮你抓住了一两个线上问题,团队的信心和投入度自然就上来了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询