恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
基于观测云构建AgentOps:LLM与AI Agent的可观测运维实战
首页
资讯中心
/
基于观测云构建AgentOps:LLM与AI Agent的可观测运维实战
基于观测云构建AgentOps:LLM与AI Agent的可观测运维实战
发布时间:2026/9/26 9:12:10
大概从 2024 年下半年开始我们团队最核心的工作变成了一个用 LLM 支撑的智能客服助理。功能跑通后第一周就被打脸线上监控面板一片绿CPU、内存、QPS 全部正常可用户投诉机器人答非所问的比例居高不下更可怕的是我们连两个最基础的问题都答不上来——这个回答到底花了多少钱同一个问题为什么昨天和今天的答案完全不一样那段时间我几乎天天在看模型 Provider 的控制台但总控台上只有聚合请求量根本定位不到具体是哪个用户、哪一轮对话、哪一段 Prompt 出了问题。这让我下定决心必须把 AgentOps 这套运维体系搭起来。这篇东西就是一次完整的实战复盘我们怎样基于观测云从零开始搭建面向 LLM 和 AI Agent 的运维体系覆盖链路追踪、指标监控、告警、成本治理、质量评估。适合正在做 LLM 应用、AI Agent、RAG 知识库的工程团队参考也适合那些早就被模型输出不稳定、token 费用不可控折磨得不轻的团队。我不会绕弯子全程都是踩过的坑和验证过的方案。1. AgentOps 要管住的新问题为什么传统监控面板在这次事故里失灵1.1 那次 429 事故面板全绿业务却崩了先说说那次让我彻底改变认知的 429 事故。某天下午客服助理的失败率突然飙升到 30%用户侧开始大量超时重试。我打开观测云的基础设施和 APM 看板主机 CPU 正常、内存正常、服务 QPS 也在预期范围内就 HTTP 错误率有点波动——但后台是异步任务前端有兜底看起来不至于崩。实际原因直到半小时后才查到模型 Provider 侧的并发配额被打满所有经过网关的请求被批量 429。传统监控盯着的是你自己的系统跑得怎么样而 LLM 应用的问题是你的系统跑得再好模型 Provider 一个限流策略就能让业务瞬间劣化。更麻烦的是这个 Provider 的配额是按分钟动态计算的控制台指标有延迟等你在网页上看到曲线已经晚了至少十分钟。从那之后我明白了一件事LLM 应用的运维对象已经从进程和接口变成了一次 LLM 调用的质量、成本、依赖状态。这就是 AgentOps 要解决的问题。1.2 LLM 应用与传统服务的四个本质差异传统可观测的三大支柱指标Metrics、日志Logs、链路Traces对应的是可预测的代码路径。一段代码输入确定、输出确定监控它的 QPS、延迟、错误码就够了。但 LLM 应用不是这样我总结下来有四个本质差异第一个差异是确定性变成了概率性。同样的 Prompt、同样的参数模型可能这次答对、下次答错改一个标点都可能改变行为。传统监控无法感知答非所问因为系统层面一切正常这需要新的观测维度——质量评估。第二个差异是每次调用都有真实的费用。传统服务调用内部接口成本是服务器折旧和电费边际成本很低。LLM 调用是按 token 计费的一个复杂的 Agent 任务可能内部循环调用十几次模型成本甚至比调用次数更敏感。如果不观测 token月底对账才发现预算超了那是真金白银的教训。第三个差异是外部依赖成了一个黑盒模型提供商。模型 API 不稳定、限流、延迟毛刺、版本悄然更新都会影响业务。你不能控制它只能观测它而且必须把依赖状态纳入自己的告警体系而不是等用户投诉。第四个差异是安全与合规风险。用户问题、知识库内容、Prompt 模板都会流经外部模型 API传统日志只记录 HTTP 请求不记录语义内容出了泄漏事件都不知道怎么追踪。这四个差异决定了 AgentOps 不是传统可观测的换皮而是一套新的数据模型、埋点策略和告警体系。1.3 观测云在 AgentOps 体系里的定位选型的时候我们评估过 LangSmith、Langfuse、Phoenix 这类专用 LLM 可观测工具也考虑过自建 Elastic Prometheus 的组合。最后选择基于观测云来做原因很实际第一公司已经有基础设施和 APM 监控在用统一平台意味着排障时不用在三个系统间反复跳转第二专用 LLM 可观测工具部署复杂数据出网合规和私有化都是问题第三观测云底座提供了 DataKit 采集器、统一存储、看板、告警、日志检索这些能力AgentOps 需要的数据模型完全可以通过 OpenTelemetry 标准协议自己定义。换句话说观测云在这个体系里的定位是数据底座和工作台负责把基础设施指标、应用链路、日志、自定义业务指标统一接入、存储、关联和展示。AgentOps 的业务逻辑——比如 LLM 调用的 Span 结构、token 成本计算、评估分数回传——由我们的应用层埋点来实现。这跟我们自己从零搭一套监控平台的差别是平台能力和告警基础设施不用重复造轮子可以专心处理 LLM 特有的语义。2. 设计与埋点先定义清楚一次 Agent 任务的模型2.1 链路模型从用户请求到 LLM 到工具再到评估我们搭 AgentOps 的第一步不是写代码而是画数据模型。如果连一条完整链路长什么样都没定义清楚后面所有看板和告警都是空中楼阁。我给一次客服任务定义的链路层次是这样的最外层是用户会话Session/Conversation中间是 Agent 的一次完整决策循环Workflow/Span往内是具体的一次 LLM 调用、一次工具调用Function Call / HTTP请求、一次 RAG 检索Embedding 向量库查询 重排序旁边还要挂上异步的评估结果Eval。用 OpenTelemetry 的术语来说就是一个根 Span 代表一次完整的用户请求或者 Agent 任务下面挂着若干个子 Span分别表示 LLM 调用、工具执行、检索操作最后评估 Span 作为独立事件或旁路节点关联到根 Trace 上。Trace ID 贯穿所有环节。这里最容易被忽略的是 Session 维度的建模。很多同学做 LLM 埋点只给单次 API 调用建一个 Span结果就是一个用户在一段对话里产生了几十条互不关联的 Trace复盘的视角完全碎片化。你在告警里看到一个高耗时 Trace点进去是某一次模型调用根本不知道这是哪场对话的第几轮、前面上下文是什么。所以我们强制要求一切从 Session 开始Session 是根每次用户输入产生一个 Workflow SpanWorkflow 内再拆 LLM Span、Tool Span、Retrieval Span。2.2 每条 Span 上挂什么属性Span 的属性设计决定了数据进到观测云之后能不能被切片、聚合、下钻。我们直接沿用了 OpenTelemetry 社区正在标准化的 GenAI 语义约定也就是gen_ai.*前缀的一组属性再叠加自己定义的业务标签。一次 LLM 调用 Span 我建议至少带这几类属性类别属性示例用途模型标识gen_ai.systemopenai/azure/ollama、gen_ai.request.modelgpt-4o-mini按模型聚合成本与性能请求参数gen_ai.request.max_tokens、gen_ai.request.temperature判断参数调整对质量的影响用量gen_ai.usage.input_tokens、gen_ai.usage.output_tokenstoken 统计与成本计算的唯一来源业务标签app、env、conversation_id、user_id、feature从业务视角切片Prompt 信息gen_ai.prompt脱敏后的摘要、agent.tool.name复现问题、回溯 Prompt 版本为什么要把业务标签看得和模型属性一样重因为后续所有成本分摊、用户粒度排障、功能对比都依赖这些维度。没有user_id财务问哪些高价值用户消耗了最多 token你答不上来没有feature产品问知识库检索这个功能是不是比直接问答贵很多你也只能干瞪眼。这些标签在埋点设计阶段就得定好后面补会异常痛苦。2.3 指标设计Token、成本、延迟、质量Span 描述的是发生了什么指标回答的是整体态势是什么。我们的指标设计分四组几乎可以看成 LLM 场景的黄金信号变形Token 与成本指标token_input_total、token_output_total、token_cost_total。Cost 不建议做成绝对值每次模型改价就要改代码更合理的做法是把 input/output token 数上报成本在观测云侧用自定义指标或者看板公式计算改价只改公式。这点后面踩坑部分还会展开。性能指标端到端延迟、首 Token 延迟TTFT、Token 吞吐tokens/s。TTFT 在流式场景里比总延迟更重要因为它直接影响用户感知的机器开始说话了的等待时间。对客服场景我们的经验是 P95 TTFT 超过 2 秒体感就会明显变差。质量指标LLM-as-Judge 的评分均值、RAG 检索命中率、答案相关性打分。这类指标不是机器自动产生的需要评估服务算出来之后上报我会在第三章详细说怎么回写。业务指标会话数、Agent 任务完成率、平均步数、工具调用成功率。平均步数是个很有意思的指标它反映了 Agent 的聪明程度——同一个任务步数越多通常意味着模型在无效探索上花了越多 token。2.4 日志与事件把对话样本接进可观测体系链路给了骨架日志给了血肉。我们的做法是保留一份对话级日志但不是把所有 prompt 和 response 都刷进去那样成本太高。我们记录的是一条消息的摘要、模型返回的摘要、关键标签、关联的 Trace ID。真正的完整对话内容只在出 bad case 时异步补采存到离线存储里。在观测云里日志和 Trace 是通过trace_id关联的。你打开一条 Trace右侧能看到当时打印的日志反过来检索日志也能跳转到对应的完整链路。这个能力在排障的时候非常有用——比如看到一个报错日志直接跳到链路看是哪次模型调用触发的上下文。我们初期没有把日志和 Trace 关联起来结果每次排障都要手动去两个系统里对时间戳效率极低这个关联的功夫一定要花。3. 基于观测云接入DataKit OpenTelemetry 打通第一条 LLM Trace3.1 接入准备工作空间、DataKit 与 SDK说完了设计下面是接入的实操。前提是你已经有一个观测云账号并创建工作空间。接着在你的工作空间里找到集成/DataKit页面会有一段安装脚本一般是带 Token 的 curl 命令贴到服务器上执行就行。DataKit 相当于一个数据采集入口它把我们应用上报的 OpenTelemetry Trace、自定义指标、日志统一接收并写入观测云后端存储我们不需要关心后端怎么存、怎么建索引。我建议 DataKit 部署在和业务应用同一台主机或者同一内网的节点上尽量减少上报链路的额外网络损耗。DataKit 默认开启了很多采集器包括主机指标、容器、Nginx 等但这些跟 AgentOps 没直接关系按需开启就行重点确认 OpenTelemetry 采集器端口是否正常监听。Observability 方案里最怕的就是采集器本身变成一个新的故障点所以 DataKit 进程挂了要有自己的告警我们当时忽略了结果有一天链路数据全没了还浑然不觉。应用侧我们用的是各语言的 OpenTelemetry SDK。这里有个选型判断我们用 Python 做服务所以选了opentelemetry-python配置 exporter 指向 DataKit 的 OTLP 地址。下面的步骤对其他语言也成立只是 SDK 初始化方式略有差异。3.2 为 LLM 调用埋点一段最小可运行的代码以一次最简单的 OpenAI 调用为例埋点代码大概长这样from opentelemetry import trace from opentelemetry.trace import SpanKind tracer trace.get_tracer(agentops.llm) def chat_with_llm(messages, modelgpt-4o-mini, **kwargs): # 创建 LLM 调用 Span with tracer.start_as_current_span(llm.call, kindSpanKind.CLIENT) as span: span.set_attribute(gen_ai.system, openai) span.set_attribute(gen_ai.request.model, model) span.set_attribute(conversation_id, kwargs.get(conversation_id, )) span.set_attribute(user_id, kwargs.get(user_id, )) span.set_attribute(feature, kwargs.get(feature, customer_service)) # 调用模型 resp openai_client.chat.completions.create( modelmodel, messagesmessages, temperaturekwargs.get(temperature, 0.3), ) # 从响应里取真实用量 span.set_attribute(gen_ai.usage.input_tokens, resp.usage.prompt_tokens) span.set_attribute(gen_ai.usage.output_tokens, resp.usage.completion_tokens) span.end() return resp有一个很常见的错误只在调用前后包一层耗时记录但不在 Span 里挂 token 用量和模型 ID。没有 token 用量成本指标就是零后面整个成本治理模块直接废掉没有模型 ID有一天你把某条线路整体切到更便宜的模型你根本没法对比前后成本变化。这属于埋点里最不能省的两条属性。我还习惯把 temperature、max_tokens 这类关键参数也写进 Span。排查输出质量问题时发现某个 prompt 出现幻觉看一眼 Span 参数发现 temperature 被配成了 0.9问题原因一步到位。3.3 RAG 检索和工具调用的 Span 怎么串真实场景里 LLM 调用不会单独出现几乎都伴随着 RAG 检索和工具调用。以我们的客服助理为例一次回答典型的子链路是Embedding 向量化用户问题 → 向量库检索 TopK → 拿到知识片段后拼接 Prompt → LLM 生成回答。这里面每一次环节都值得单独建 Span。Embedding 调用我建一个llm.embeddingSpan挂gen_ai.operation.nameembed向量库查询在观测云里实际是去 ClickHouse 或 Milvus 查建一个tool.vector_searchSpan挂集合名、检索召回数重排序如果用了 Rerank 模型单独建rerank.callSpan。这些 Span 的父子关系严格按调用顺序来LLM 生成回答的 Span 是它们共同的下游。还得注意工具调用的跨系统问题。Agent 调用一个工具查订单 API、查库存 API这个工具调用链路上可能还有 HTTP 客户端埋点会生成一个独立的 HTTP Span。我们要做的不是让它孤零零挂着而是把工具 Span 和 HTTP Span 通过 context propagation 串起来。具体做法是在调用工具前把当前 Trace Context 注入到 HTTP 头里让下游服务的链路自动挂到同一个 Trace 上。这个工作如果不在埋点阶段完成事后排查 Agent 为什么拿到错误工具结果你看到的链路是断的Agent 说调用了查询 API但 API 侧没有任何 trace 上下文。3.4 评估结果如何异步回写链路质量评估这种环节绝不能放进线上主链路同步执行。我们最初用 GPT-4o 给客服回答质量实时打分结果发现一次回答延迟多了 3 秒直接触发了超时告警。后来改成异步队列线上只记录 Trace ID 和必要的上下文调用完成之后把样本丢进队列由独立的评估服务消费调用一个便宜的小模型或者可用的判断模型给回答打分最后把分数写回。写回的方式有两种我们结合使用。一种是在评估 Span 上打标评估服务同样用 OpenTelemetry 初始化一个 Span设置trace_id指向原始 Trace再挂llm.judge.score、llm.judge.aspects这些属性。另一种是直接往原始 Trace 的上下文里再写入一个评估事件观测云支持链接到已有 Trace。无论哪种目标都是让质量在链路里可见。有一点需要注意Span 一旦结束OTel 规范里是不允许再改属性的所以别尝试在异步评估结束之后去改原始 LLM Span 的属性正确做法是创建独立的评估 Span 并与之关联。我们在观测云里看效果打开任意一条客服 Trace除了 LLM 调用外还能看到旁边挂着一个 evaluate 子 Span上面写着准确性、相关性、幻觉分数资深工程师扫一眼就知道这条回答为什么出了问题。4. 从数据到决策看板布局与告警规则4.1 看板四块成本、性能、质量、业务数据接入只是开始真正每天要用的是一套能让人快速做决策的看板。我们的主看板划分成四块布局是有讲究的最上面是成本区因为老板每天问中间是性能和错误区是值班工程师最关心的下面是质量与业务区给产品和算法同事看。成本区放了三个核心图按模型分组的每日 token 趋势输入/输出堆叠、每日估算费用、按功能模块feature分组的费用占比饼图。费用估算在观测云里用看板公式计算把 input token 数乘以输入单价、output token 数乘以输出单价再按天聚合。模型改价或者切换模型时只需要更新公式不用动采集端。性能和错误区放的是端到端延迟和 TTFT 的 P50/P95 趋势、模型错误码分布429/500/超时、Agent 任务失败率。质量区放的是LLM 评估得分的趋势线、RAG 检索召回率和命中率、幻觉检测结果分布。业务区放的是会话总量、Agent 完成率、平均步数、工具调用成功率。这四个区合在一起基本覆盖了花的钱、跑的慢、答得差、业务不OK四类问题。4.2 告警规则怎么设计才不至于狼来了LLM 应用的告警设计我的原则是指标可以多埋告警必须少而精。告警数量失控的结果就是没人看我们第一批配置了二十多条规则两周后只剩五条真正生效。我们保留下来最有效的三条规则值得分享。第一条是费用突增告警当每五分钟累计估算成本超过过去三小时同时间段均值的 3 倍时触发。成本异常上升通常意味着 Agent 陷入循环调用或者 Prompt 意外膨胀这是 LLM 应用特有的毁灭性 bug。第二条是 429 占比告警五分钟内 429 错误数超过总调用数的 5% 就触发。等眼看 Provider 控制台永远是滞后报警不如在自己这边算占比更贴近业务体感。第三条是质量分滑落告警LLM 评估分滑动窗口均值比前一日下降超过 15%。这个规则触发过两次一次是上游换了模型版本一次是我们改了 Prompt 模板都靠它在灰度阶段拦下来了。除此之外还有一些常规的端到端延迟 P95 超阈值、错误率超阈值、Agent 任务完成率低于 90%。但这些和普通接口告警逻辑一致不赘述。4.3 一次标准排障路径从告警到 Trace 到 Prompt告警的价值要落实在排障路径上。我拿一个真实案例演示我们的标准流程某天收到费用突增告警后第一反应不是去看模型 Provider 控制台而是打开观测云看板点进费用异常的那段时间窗口按 feature 过滤看哪个功能在烧钱。定位到订单查询功能后点 trace 列表按成本倒序排列找到最贵的一条 Trace展开链路发现 Agent 陷入了 18 步循环不停地调用一个返回空结果的工具每循环一次都产生一次 LLM 调用 token 消耗。再往下钻到某一次 LLM Span看到模型输出的 Thought 部分是结果为空我继续尝试另一种查询方式而工具返回的数据结构因为上游接口字段变更已经变了模型的解析逻辑全部落空。问题根因是上游 API 返回了不兼容的 JSON 结构Agent 误判为工具未生效于是不断重试。这个链路如果没有 Trace 关联、没有 token 成本打标我们大概率会花半天时间在日志里捞关系而不是在十分钟内精确定位到一次工具响应格式变化。看板负责告诉你哪里不对Trace 负责告诉你为什么不对这就是 AgentOps 排障闭环。5. 生产环境里踩过的六个坑5.1 Prompt 与敏感信息脱敏这是底线问题必须放在最前面。LLM 可观测本质上是把 prompt 和响应数据送进可观测平台如果不过滤用户手机号、姓名、地址、内部文档全文就会跟着 Span 属性一起进存储。一旦入库不管后续能不能删都属于一次数据事件。我们的做法分三层第一层所有gen_ai.prompt属性在上报前做 PII 脱敏和截断保留前 200 个 Token命中手机号、邮箱、身份证等正则直接打码第二层Span 上彻底不挂对话原文只挂摘要和业务 ID完整文本统一存到单独的脱敏对象存储第三层内部文档做权限隔离知识库内容除非显式标记为可观测否则绝不进入链路。如果你现在还没做脱敏我建议立刻停掉 prompt 属性上报宁可牺牲排查便利不要冒数据泄漏的险。5.2 全量采集不如分层采样初期我们天真地认为全量保留所有 trace 最稳妥结果一周后存储成本和查询性能都崩了——客服系统每天几十万次调用全量 Span 是天文数字。后来我们用分层采样方案所有错误和慢调用延迟超过 P95 的全量保留带评估结果的优质样本保留 20%普通成功调用保留 5%~10%指标数据永远是全量聚合的。采样维度一定要挂在 Session 而不是单条 Span 上否则会出现同一场对话一半有 trace 一半没有的尴尬局面。观测云本身支持在写入前做过滤也可以用 OTel SDK 的 Sampler 实现我们用的是基于 Trace ID 的尾部采样策略先把 Span 全量上报由观测云端做采样决策。这样一个复杂 Agent 任务的整条链路只要进入采样池就是从根到叶子完整保留。5.3 Session ID 没打通导致链路断裂这是一个非常隐蔽的坑。我们在接入消息队列后用户请求先从 HTTP 入口进来然后扔进 Kafka 异步处理消费端再发起 LLM 调用。由于没有把 Trace Context 传播到消息头HTTP 入口的 Trace 和消费端产生的 Trace 成了两条完全不相干的链路。结果就是用户在 App 上等的这段时间从可观测视角看是业务结束了其实真正的 Agent 工作才刚刚开始。解决办法有两个任选其一都行一是用 OpenTelemetry 的消息传播扩展生产者在发送消息时把 trace context 序列化进消息头消费者在接收时反序列化并恢复 parent span二是更简单粗暴在消息体里手动带 conversation_id 和 trace_id消费端收到后创建一个新 Span 并把 trace_id 指向原始 Trace。我们最后选了后者改动小、逻辑直观排障时一条完整链路从用户点击贯穿到模型返回。5.4 评估回传放异步别拖垮主链路这一点在第三章提过但值得单独列为教训。第一次尝试把正确答案照进评估里的时候我们在主请求里同步调用了另一个更贵的模型做 LLM-as-Judge。测试环境没暴露问题上线后 P95 延迟从 2 秒飙到 5 秒用户体验直接受损。后来评估服务全面异步化可靠性提升还意外获得了另一个好处评估队列本身成了一个缓冲模型 Provider 限流时不会连带核心业务。异步评估最大难点是怎么在评估结果出来之后准确关联到原链路。我们依赖的是把 trace_id、conversation_id、message_id 三件套一起作为消息内容传给评估服务评估结束时回写。这里一定要留意消息丢失的场景评估样本丢了不可怕怕的是丢了不知道可以在评估服务侧加一个成功处理数指标与线上样本总数对账。5.5 成本标签缺失导致无法分摊我对这个坑的印象深因为实在被坑得太狠。初版埋点里我们没有给 LLM Span 打user_id和feature标签结果上线一个月后财务要求成本分摊到业务线我们对着观测云看板干瞪眼——只有模型维度和总 token 数根本分不出哪个业务线花了多少。最后只能靠临时在日志里按关键字解析出一个大概又慢又准。成本标签的设计建议是至少在 Span 上带app、feat、env、user_id、conversation_id五个维度。如果你们的 Agent 服务由多个上游系统调用再加一个channel表示来源渠道。这些标签是成本报表的切片维度也是后续做用户级异常检测的依据越早设计越省事。5.6 多 Agent 场景的链路拼装当我们从单 Agent 演进到多 Agent 协作比如一个主管 Agent 分配任务、多个子 Agent 并行处理后链路开始变得复杂一个任务的 Span 树变得很深很宽子 Agent 的模型调用散落在不同进程甚至不同机器上。我们现在的做法是在框架层统一创建一个 Workflow 级别的根 Span子 Agent 的全部调用通过 context 拼接上去同时给每个子 Agent 打一个agent.name和agent.role的标签方便按角色聚合表现。多 Agent 场景里尤其要注意循环引用和扇出爆炸一个子 Agent 回调主管 Agent主管再给他派新任务如果不像上面那样统一建 Workflow Span最终链路会乱成一团无法阅读。我们在观测云里看到过一次 40 多个子 Agent 并行任务的 Trace没有 Workflow 根展开就是灾难。6. 从可观测到可治理我们正在做的三件事6.1 评估集进入发布准入可观测解决的是线上发生了什么但光知道不够我们开始把观测数据反向接入研发流程。现在每一次模型版本切换、Prompt 模板更新都要先跑一遍固定的评估集把新的评估得分和线上历史得分对比低于基线就不允许发布。这个评估集的构建不是拍脑袋写的而是从观测云里持续沉淀的 bad case 里挑出来的覆盖了客服、检索、工具调用等高频场景。观测数据在这里的角色是裁判的数据来源发布前的评估集样本、发布后的线上质量分、两者对照。我们用脚本定时从观测云的质量看板拉取打分趋势自动生成回归报告出了问题可以在代码评审阶段就把新 Prompt 挡回去。这个过程让可观测从被动的排障工具变成了主动的质量门禁。6.2 Bad Case 回归机制我们专门建了一个金矿流程每周从观测云里筛选评分最低、成本最高、用户投诉最多的若干条 Trace自动导出完整对话记录已脱敏进离线评估集。下个迭代开始前先在离线环境验证这些 bad case 是否被新 Prompt 或新模型修复修复率低于 60% 就要重新调整方案。这套机制最值钱的地方在于它把偶发的、概率性的模型问题变成了可追踪的工程问题。同一类幻觉、同一个 RAG 检索失败被解决了多少次都是有据可查的而不是靠记忆力感觉好像好了一点。Bad case 回归和发布准入两块合起来构成了我们的质量闭环线上问题 → 观测云发现 → 样本沉淀 → 离线回归 → 新版本发布 → 再上观测云验证。6.3 反馈与观测数据的飞轮最后一件事我们还在验证中但方向已经确定把用户的显式反馈点赞/点踩/追加问题和隐式反馈是否放弃追问、是否转人工写回链路和 LLM 调用、评估分数放在同一个 Trace 里。有了这个飞轮AgentOps 就不仅能回答哪里出了问题还能回答哪些问题对用户最重要——转人工的那一轮对话、用户反复重试的那类问题就是整个系统最值得优化的部分。现在每次周会上我们的核心决策依据已经不再是谁的直觉而是观测云看板里的几个关键数字每万次会话成本、质量得分趋势、bad case 修复率。如果让我重新搭一遍这套体系我会把成本标签设计和评估异步回传放在第一天就做而不是先跑通功能再补观测——补观测的代价永远比一开始就设计好的代价要高得多。