Skip to content

28|报告与 Trace:带证据的产出

上一篇让会话能持久化。这一篇讲最终产出:把排查过程组织成带证据的报告。

ops-assistant 的产出不是一段自由文本,而是结构化排查报告。运维场景对报告的要求很明确:每条结论必须有证据来源,区分已确认事实和待验证推断,能追溯模型是怎么得出结论的。本篇讲报告生成和支撑它的 trace。

报告的字段设计

报告最怕把"已确认的事实"和"建议继续检查的动作"混在一起。字段设计时就分开:

AIOps 概念图:报告字段分层

python
from pydantic import BaseModel

class OpsReport(BaseModel):
    symptom: str                    # 现象:材料已证明的
    confirmed_facts: list[str]      # 已确认事实
    likely_causes: list[str]        # 推断原因(带不确定性)
    recommended_checks: list[str]   # 建议检查项(下一步动作)
    evidence: list[dict]            # 证据,每条带来源
    risk_level: str
    confidence: str                 # 系统算的,不是模型填的

symptomconfirmed_facts 只能写材料已证明的内容。likely_causes 是基于证据的推断,必须标注不确定性。recommended_checks 是下一步动作,不是已执行的操作。"建议检查 slowlog"不能写成"已确认 slowlog 异常"。字段命名本身就在强制执行这条区分。

证据必须可回溯

报告里每条结论都要能追溯到来源。[1] 这种编号不够,要链接到原始文档片段或保存的检索记录。值班人员点编号就能查看"模型是根据哪段材料得出这个结论的"。

AIOps 概念图:证据可回溯

python
evidence = [
    {
        "id": 1,
        "source": "nginx-error-log",
        "time": "2026-06-26T14:32:01Z",
        "snippet": "2026-06-26 14:32:01 error: upstream timed out",
        "trace_ref": "traces/s1-step3-read_log.json",
    },
]

trace_ref 指向完整 trace。报告里只放摘要 snippet,需要看完整证据时点开 trace。没有回溯能力的证据约束只是形式合规。

confidence 不能模型自由填

报告里的 confidence 字段不能由模型自由填写。模型有高估自己置信度的倾向——它倾向于对自己的结论打高分。

confidence 由系统根据证据充分程度算:

python
def calculate_confidence(evidence: list[dict], cross_validated: bool) -> str:
    if len(evidence) >= 3 and cross_validated:
        return "high"
    if len(evidence) >= 2:
        return "medium"
    return "low"

证据来源越多、交叉验证越充分,置信度越高。单独一条日志支撑的结论,最高只能标 medium。模型只产出结论和证据,置信度由系统按规则算,不让模型自评。

Trace 记录完整链路

trace 记录 agent 的完整执行过程:每一轮调用了什么、工具返回了什么、模型推理了什么。它是排查"模型为什么答错"的唯一证据。

python
def save_session_trace(session_id: str, state: SessionState) -> None:
    trace = {
        "session_id": session_id,
        "turns": state.trace,    # 每轮的工具调用、中间结论
        "messages": state.messages,
        "usage": state.usage,
    }
    Path(f"traces/{session_id}.json").write_text(
        json.dumps(trace, ensure_ascii=False, indent=2), encoding="utf-8",
    )

trace 和报告不同。报告是给值班人员看的结论,trace 是给开发者排查问题用的过程记录。报告丢了能从 trace 重建,trace 丢了就很难还原历史排查过程。

评估不只看答案

agent 是多步交互系统,结果正确不代表过程合规。一个答对了的报告,可能是模型恰好猜中了,而不是基于证据推理出来的。

完整评估覆盖几个维度:检索质量(是否找到了正确的 Runbook)、工具使用合规性(是否滥用了命令工具)、推理过程(结论是否有证据支撑)。只看最终答案的评估会漏掉过程中的问题——模型可能用了不该用的工具、引用了不相关的文档、跳过了必要的验证步骤,最后却给出了正确答案。

python
def evaluate_session(session_id) -> dict:
    trace = load_trace(session_id)
    return {
        "retrieval_precision": check_retrieval(trace),
        "tool_compliance": check_tool_usage(trace),
        "evidence_support": check_evidence(trace),
        "final_answer_correct": check_answer(trace),
    }

把好的 session 提取成测试用例,加入回归测试集(第 5 篇)。下次改 Prompt 或换模型时,跑这些用例看过程是否仍然合规。

Trace 分级保留

Trace 的保留周期不是越久越好。完整 trace 包含大量上下文数据,长期存储成本高。

最近 7 天的 trace 保留完整细节,7~30 天的只保留摘要和结论,30 天以上的归档到冷存储。审计日志(操作记录)永久保留,不受 trace 清理策略影响——trace 是过程记录可以压缩,审计是合规记录必须留全。

报告之后

报告和 trace 讲完了,ops-assistant 的核心功能完整:能听懂任务、能看对的材料、能安全地一步步做、能协作、能产出带证据的报告。

最后一篇讲上线。本机能跑不代表能放值班入口——进程托管、健康检查、可观测性、成本控制、异常降级,这些是上线必须处理的。