Home Projects Blog Resume Contact 中文
Back to list
2026年7月5日 1,950 words 5 min read

06:结果可信:模型生成产物以后为什么还要继续验证

从模型 final answer 之后的 validating 阶段出发,介绍 RunLens 怎样用产物契约、Stop Hook 和证据索引检查文件结构、内容格式与引用真实性。

#RunLens#产物验证#Evidence#Agent Runtime

06:结果可信:模型生成产物以后为什么还要继续验证

上一篇介绍了 RunLens 怎样控制循环和失败恢复。模型最终返回 final answer 后,AgentLoop 会停下来,Runtime 随即进入 validating。

这个阶段决定了一次 Run 能否交付。

模型可以生成结构完整、语言流畅的内容,也可能遗漏文件、写错枚举、缺少报告章节,或者引用一条源 CSV 中从未出现过的反馈。

RunLens 把“模型结束”和“业务完成”分成两个判断。

Final answer 负责结束模型循环,Artifact Validation 负责确认交付结果。

模型结束之后,文件还要接受检查

Feedback Analysis 要交付三个文件:

artifacts/feedback_analysis.json
artifacts/product_backlog.json
artifacts/insight_report.md

模型结束时可能出现几种情况:

  • 只写了两个文件。
  • JSON 可以解析,但缺少必需字段。
  • priority 写成 high,而业务契约要求 P0–P3
  • Markdown 报告缺少风险章节。
  • analysis 和 backlog 引用了同一个虚构 feedback_id。
  • feedback_id 真实,evidence_text 却是模型改写后的内容。

这些结果仍然可以读,业务可信度已经发生变化。

我希望 Run Status 能准确表达这次结果是否满足交付条件,因此验证逻辑放在 Runtime 的最终阶段统一执行。

ArtifactContract 先定义什么叫交付结果

Plugin 使用 ArtifactContract 声明每个最终产物。

主要字段包括:

字段作用
name工作区相对路径
description产物用途
label前端展示名称
audienceuser 或 developer
sensitivity敏感级别
required是否属于必需交付
schemaJSON 轻量校验规则
required_headingsMarkdown 必需标题
evidence_fields证据 ID 在 JSON 中的路径

Feedback Analysis 的三个 ArtifactContract 分别定义:

Feedback Analysis JSON

  • 必需文件。
  • 包含 itemsfailed_batches
  • sentiment 使用四类枚举。
  • severity 使用四类枚举。
  • items.feedback_id 需要回溯到 Evidence Index。

Product Backlog JSON

  • 必需文件。
  • 包含 items
  • priority 使用 P0–P3
  • items.evidence_feedback_ids 需要回溯。

Insight Report Markdown

  • 必需文件。
  • audience 为 user。
  • 包含七个规定标题。

ArtifactContract 同时服务验证、Manifest 和前端元数据,避免三处分别维护产物规则。

Stop Hook 负责最后一道质量门

Runtime 初始化时,register_builtin_hooks() 会根据 ArtifactContract 自动注册 Stop Validators。

模型循环结束后,HookManager 触发 Stop 事件。

Stop 属于 Blocking Hook。任意 Validator 返回 blocked,最终 Run 会进入 failed。

与 PreToolUse 不同,Stop 会执行全部 Validator,再汇总失败原因。这样一次 Run 可以同时暴露缺失文件、JSON 枚举和证据引用问题。

当前主要有四类 Validator。

第一道门:必需文件是否存在

RequiredOutputValidationHook 检查每个 required artifact 的真实路径。

如果模型只创建了两个 JSON,报告缺失,Hook 会记录:

missing required files: artifacts/insight_report.md

Plan 的报告步骤也会因为 artifact success criteria 未满足而保留 failed 状态。

这一层解决的是最基础的交付完整性。

模型在 final answer 中写“报告已生成”只能结束循环,Runtime 会继续检查工作区中的真实文件。

第二道门:JSON 字段和枚举是否正确

JsonOutputValidationHook 会读取 ArtifactContract 中的 schema。

当前项目使用轻量规则:

{
  "required_fields": ["items", "failed_batches"],
  "enum_fields": {
    "items.sentiment": ["positive", "neutral", "negative", "mixed"],
    "items.severity": ["low", "medium", "high", "critical"]
  }
}

Validator 会检查:

  • 文件能否解析为 JSON。
  • 顶层必需字段是否存在。
  • 指定路径中的枚举值是否位于允许集合。

例如:

{
  "priority": "urgent"
}

Backlog Validator 会返回 invalid priority,因为业务契约只接受 P0P1P2P3

当前规则聚焦最关键结构,后续可以升级为完整 JSON Schema 或 Pydantic 产物模型。

第三道门:Markdown 结构是否完整

MarkdownSectionValidationHook 检查报告是否包含规定标题。

Feedback Analysis 报告需要:

# FeedbackLens Insight Report
## Product Context
## Executive Summary
## Top Pain Points
## Evidence
## Recommended Actions
## Risks And Unknowns

这些标题对应产品负责人阅读报告时最关心的结构:背景、摘要、痛点、证据、行动和风险。

模型遗漏 ## Risks And Unknowns 时,报告仍然可读,交付契约却缺少风险说明。Stop Hook 会把这次 Run 标记为 failed。

当前实现使用字符串包含检查,适合固定标题契约。更复杂的文档结构可以在后续接入 Markdown AST。

第四道门:证据是否来自原始 CSV

前三道门检查格式和结构,Evidence Validation 检查事实来源。

Feedback Analysis 的业务要求是:

  • 每条分析引用真实 feedback_id。
  • 每个 Backlog Item 引用真实证据 ID。
  • analysis 中的 evidence_text 来自对应反馈原文。

只检查两个产物是否互相一致还不够。它们可能共同引用一个模型虚构的 ID。

因此 RunLens 在读取 CSV 时建立独立 Evidence Index。

Evidence Index 怎样建立回溯关系

read_feedback_csv 完成读取和列校验后,会写入:

runtime/evidence_index.json

结构大致是:

{
  "source": "sample_feedback.csv",
  "source_hash": "...",
  "items": {
    "fb_001": {
      "row_hash": "...",
      "text": "导出周报太慢了……"
    }
  }
}

Source Hash

对整份 CSV 原始字节计算 SHA-256,记录本次运行使用的源文件版本。

Row Hash

每条反馈先规范化为排序后的 JSON,再计算 SHA-256。它可以标识某个 feedback_id 对应的完整行内容。

Original Text

保存原始反馈文本,用于验证 evidence_text。

Evidence Index 由确定性工具创建,Stop Hook 读取它完成最终回查。

自洽的虚构证据为什么仍然失败

假设模型生成:

// feedback_analysis.json
{
  "items": [
    {
      "feedback_id": "fb_999",
      "pain_point": "导出速度慢"
    }
  ],
  "failed_batches": []
}

Backlog 同时引用:

{
  "evidence_feedback_ids": ["fb_999"]
}

两个文件内部关系完全一致。EvidenceCitationValidationHook 读取 Evidence Index 后,会发现 fb_999 查无对应源行。

验证路径是:

Stop
→ 读取 evidence_index.json
→ 收集 analysis 和 backlog 引用 ID
→ 对照真实 ID 集合
→ missing evidence ids: fb_999
→ Hook blocked
→ Run failed

这种检查聚焦来源真实性,文件内部一致性只覆盖其中一部分。

ID 真实,原文片段也要匹配

模型可能引用真实 fb_001,同时写入一段更顺畅的概括:

每周导出报告需要等待很长时间,影响团队协作效率。

源文本可能是:

导出周报太慢了,我们团队每周五都要导出,等三分钟很影响效率。

RunLens 要求 evidence_text 是源文本中的非空片段。

如果模型写的是改写句,Evidence Validation 会记录 text mismatch。

这种规则让“分析结论”和“原始证据引用”保持分离:

  • pain_point 和 suggested_action 可以归纳。
  • evidence_text 保留可直接核对的源片段。

验证失败后 Run 会发生什么

Stop Hook blocked 后,Runtime 会:

  1. 把最终 status 改为 failed。
  2. 写入 error_message。
  3. 将相关 Plan Step 标记为 failed。
  4. 发布 hook.blocked。
  5. 发布 artifact.rejected 或 artifact.validated。
  6. 发布 run.failed。
  7. 聚合失败 Metrics。

已经生成的文件会保留在工作区。开发者可以直接查看错误内容,前端也能通过 Plan 和 Events 确认失败发生在最终验证阶段。

Artifact 事件当前带有一部分路径匹配逻辑。跨产物证据错误有时仍会让已存在 Artifact 显示 validated,因此最终可交付性以 Run Status 和 Stop Hook 结果为准。

Prompt 和验证共同组成质量边界

Feedback Analysis 的 Evidence 要求同时出现在:

  • Skill 指令。
  • Business Prompt Fragments。
  • ArtifactContract evidence fields。
  • Evidence Index。
  • Stop Validation。

这些位置分工明确:

层次作用
Skill提供正确任务方法
Prompt让模型知道输出要求
Tool创建真实证据索引和文件
Contract声明可交付结构
Stop Hook执行最终确定性检查

模型在生成阶段拥有清楚指导,Runtime 在交付阶段拥有独立判断。

当前校验还可以怎样增强

这一版已经覆盖文件、关键字段、枚举、标题和源证据。后续可以继续增加:

  • 完整 JSON Schema。
  • Pydantic 产物模型。
  • Markdown 标题顺序和唯一性。
  • Backlog acceptance criteria 和 metric 的字段约束。
  • Source Hash 与外部数据版本管理。
  • 产物签名和审核状态。
  • 业务 Validator 插件接口。

增强方向仍然围绕同一目标:让 completed 表达真实交付条件。

小结

RunLens 使用 ArtifactContract 定义产物,Stop Hook 执行最终质量门,Evidence Index 把模型引用回溯到原始 CSV。

文件存在、JSON 结构、Markdown 章节和 Evidence 来源共同决定 Run 能否 completed。模型可以完成内容生成,Runtime 负责确认这些内容达到了业务交付条件。

下一篇继续看验证结果怎样进入运行证据:Events、Trace、Metrics 和 Manifest 如何把一次 Run 的因果链展示出来。