[M-AI-05-03] 实现 Feynman Executor 与结构化输出验证 #306

Closed
opened 2026-06-21 15:53:27 +08:00 by wangdl · 1 comment
Owner

类型 / 标签

  • backend
  • feynman
  • ai
  • validation

风险等级

P1(验证缺失会导致非法输出进入数据库;Prompt 语义偏离会导致评估质量下降)

依赖

  • M-AI-05-02(Definition 和 Snapshot 就绪)

目标

将现有 Feynman AI 评估逻辑适配到统一 Execution Engine,保持原 Prompt 和业务语义。Executor 只负责调用模型并返回结构化输出,不写数据库。

Executor

新增 FeynmanExecutor,职责:

  1. 从 Snapshot 构造模型消息
  2. 使用冻结的 Prompt
  3. 通过 AiGatewayService 调用模型
  4. 接收 AbortSignal
  5. 返回原始或解析后模型输出
  6. 不写数据库

禁止:直接调用 Provider SDK、自行解析模型凭据、读取 Controller DTO、直接读取或修改业务表、创建 FocusItem、创建 ReviewCard、修改 Job 状态、自行实现 BullMQ Retry。

输出 Schema

严格依据 M-AI-05-01。需要区分:模型原始输出、JSON Repair 后输出、Schema 验证后输出、业务验证后输出。

Business Validator

至少根据真实 Schema 验证:score 范围、正确性枚举、反馈非空、missingPoints 数量与长度、misconceptions 合法性、建议数量、禁止空对象冒充成功、禁止异常大文本、禁止模型指令或代码块进入结构化字段。

Reference Validator

如果输出包含引用:引用 ID 必须存在、只能引用 Snapshot 中允许的资料、不得引用其他用户知识库、不得伪造 URL 或内部路径。没有引用字段时,不得为了形式强行生成引用。

兼容对比

使用固定 Fixture 对比 Legacy Workflow 和新 Executor:Prompt Key、系统提示、用户消息、模型参数、输入上下文、输出业务语义、错误分类。不要求自然语言逐字相同。

影响范围

src/modules/ai-job/executor/src/modules/ai-job/validator/src/modules/ai-gateway/

验收标准

  • 正常输出通过全部验证
  • 非法 JSON 被拒绝(含错误分类)
  • JSON Repair 可控(有开关,不修改语义)
  • Schema 错误被拒绝(缺字段、类型错误)
  • score 越界被拒绝
  • 空反馈被拒绝
  • 非法引用被拒绝(引用不存在的资料、跨用户知识库、伪造 URL)
  • AbortSignal 生效(取消后不再等待模型)
  • 所有调用经过 AiGateway(验证通过日志或测试 spy)
  • Executor 无数据库副作用
  • 使用固定 Fixture 对比 Legacy 和新 Executor 的输出业务语义
  • 单元测试通过

建议执行顺序

第 3 个执行(依赖 02)

## 类型 / 标签 - backend - feynman - ai - validation ## 风险等级 P1(验证缺失会导致非法输出进入数据库;Prompt 语义偏离会导致评估质量下降) ## 依赖 - M-AI-05-02(Definition 和 Snapshot 就绪) ## 目标 将现有 Feynman AI 评估逻辑适配到统一 Execution Engine,保持原 Prompt 和业务语义。Executor 只负责调用模型并返回结构化输出,不写数据库。 ## Executor 新增 `FeynmanExecutor`,职责: 1. 从 Snapshot 构造模型消息 2. 使用冻结的 Prompt 3. 通过 AiGatewayService 调用模型 4. 接收 AbortSignal 5. 返回原始或解析后模型输出 6. 不写数据库 禁止:直接调用 Provider SDK、自行解析模型凭据、读取 Controller DTO、直接读取或修改业务表、创建 FocusItem、创建 ReviewCard、修改 Job 状态、自行实现 BullMQ Retry。 ## 输出 Schema 严格依据 M-AI-05-01。需要区分:模型原始输出、JSON Repair 后输出、Schema 验证后输出、业务验证后输出。 ## Business Validator 至少根据真实 Schema 验证:score 范围、正确性枚举、反馈非空、missingPoints 数量与长度、misconceptions 合法性、建议数量、禁止空对象冒充成功、禁止异常大文本、禁止模型指令或代码块进入结构化字段。 ## Reference Validator 如果输出包含引用:引用 ID 必须存在、只能引用 Snapshot 中允许的资料、不得引用其他用户知识库、不得伪造 URL 或内部路径。没有引用字段时,不得为了形式强行生成引用。 ## 兼容对比 使用固定 Fixture 对比 Legacy Workflow 和新 Executor:Prompt Key、系统提示、用户消息、模型参数、输入上下文、输出业务语义、错误分类。不要求自然语言逐字相同。 ## 影响范围 `src/modules/ai-job/executor/`、`src/modules/ai-job/validator/`、`src/modules/ai-gateway/` ## 验收标准 - [ ] 正常输出通过全部验证 - [ ] 非法 JSON 被拒绝(含错误分类) - [ ] JSON Repair 可控(有开关,不修改语义) - [ ] Schema 错误被拒绝(缺字段、类型错误) - [ ] score 越界被拒绝 - [ ] 空反馈被拒绝 - [ ] 非法引用被拒绝(引用不存在的资料、跨用户知识库、伪造 URL) - [ ] AbortSignal 生效(取消后不再等待模型) - [ ] 所有调用经过 AiGateway(验证通过日志或测试 spy) - [ ] Executor 无数据库副作用 - [ ] 使用固定 Fixture 对比 Legacy 和新 Executor 的输出业务语义 - [ ] 单元测试通过 ## 建议执行顺序 第 3 个执行(依赖 02)
wangdl added this to the M-AI-05 Feynman 与 ReviewCard 可靠链路 milestone 2026-06-21 15:53:27 +08:00
wangdl added the
priority:p1
area:ai
backend
labels 2026-06-21 15:53:27 +08:00
Author
Owner

开发完成评论

完成内容

  • 实现 FeynmanExecutor
    • 从 Snapshot 构造用户消息(与 Legacy FeynmanEvaluationWorkflow.execute() 格式一致)
    • 通过 AiGatewayService.generate() 调用模型(feature=feynman-evaluation, promptKey=feynman-evaluation, outputSchema=FeynmanEvaluationResultSchema
    • 接收 timeoutMs 并传递给 AiGateway
    • 不写数据库、不修改 Job 状态、不自实现 Retry
  • 实现 FeynmanBusinessValidator(11 项验证规则):
    • score [0,100] 整数、clarityLevel 枚举、summary 非空 1-2000
    • strengths/weaknesses/blindSpots/suggestions 数组 ≤10 项,每项 ≤500 字符
    • isBeginnerFriendly boolean、jargonUsage 枚举、analogyQuality 可选枚举
    • 禁止空对象冒充成功、禁止异常大文本、禁止代码块/模型指令前缀
  • 实现 FeynmanReferenceValidator
    • URL 检测(所有文本字段 + summary 独立检查)
    • Email 检测(PII 泄露防护)
    • 签名预留 _snapshot? 参数(未来扩展引用范围验证)
  • 更新 AiJobModule:注册 FeynmanExecutor + FeynmanBusinessValidator + FeynmanReferenceValidator

验证链

模型原始输出
  → AiGatewayService.parseJson() (JSON Repair + Zod Schema)
  → FeynmanBusinessValidator.validate()
  → FeynmanReferenceValidator.validate()
  → 返回 validatedOutput

修改文件

  • src/modules/ai-job/feynman-executor.ts(新增,88 行)
  • src/modules/ai-job/feynman-validator.ts(新增,225 行)
  • src/modules/ai-job/feynman-executor.spec.ts(新增,315 行)
  • src/modules/ai-job/ai-job.module.ts(修改,+7 行:4 imports + 3 providers)

代码证据

  • feynman-executor.ts:43-79 — execute() 核心逻辑(消息构造 + AiGateway 调用 + timeout 传递)
  • feynman-validator.ts:105-172 — BusinessValidator.validate()(11 项完整验证规则)
  • feynman-validator.ts:207-247 — ReferenceValidator.validate()(URL/Email 检测)
  • feynman-validator.ts:179-198 — validateStringArray()(数组字段通用验证)
  • feynman-executor.ts:2-4 — 仅注入 AiGatewayService(不注入 PrismaService — 零 DB 副作用)

测试情况

  • 已运行命令:
    • npx jest --testPathPatterns="feynman-executor"
    • npx jest --testPathPatterns="ai-job"
  • 结果:
    • 新增 29 tests:Executor(4) + BusinessValidator(18) + ReferenceValidator(3) + 结构验证(4)
    • 全部通过:15 suites, 310 passed, 18 skipped, 0 failed
    • TypeScript 编译:新文件零错误

与 Legacy 的兼容性

  • 消息构造逻辑与 FeynmanEvaluationWorkflow.execute() (workflow.ts:18-29) 一致
  • promptKey/promptVersion/outputSchema 与 Legacy 完全相同
  • 消息格式:【知识点标题】+ title + 【知识点原文】+ content + 【用户的费曼解释】+ explanation
  • modelTier 使用 Snapshot 中 Definition 指定的 tier(与 Legacy 一致为 primary

未完成 / 风险

  • Executor 未在 AiJobExecutionEngine 中接入(留待 M-AI-05-05 入口路由 + Engine 分派)
  • Projector 留待 M-AI-05-04 实现
  • Engine 中需要增加 feynman_evaluation 的 jobType 分支(或改为通用 Registry 驱动的 Executor 分派)

是否建议进入 Review

  • 是 — Executor + 验证链已完成,建议审核后启动 M-AI-05-04
## 开发完成评论 ### 完成内容 - 实现 `FeynmanExecutor`: - 从 Snapshot 构造用户消息(与 Legacy `FeynmanEvaluationWorkflow.execute()` 格式一致) - 通过 `AiGatewayService.generate()` 调用模型(feature=`feynman-evaluation`, promptKey=`feynman-evaluation`, outputSchema=`FeynmanEvaluationResultSchema`) - 接收 timeoutMs 并传递给 AiGateway - 不写数据库、不修改 Job 状态、不自实现 Retry - 实现 `FeynmanBusinessValidator`(11 项验证规则): - score [0,100] 整数、clarityLevel 枚举、summary 非空 1-2000 - strengths/weaknesses/blindSpots/suggestions 数组 ≤10 项,每项 ≤500 字符 - isBeginnerFriendly boolean、jargonUsage 枚举、analogyQuality 可选枚举 - 禁止空对象冒充成功、禁止异常大文本、禁止代码块/模型指令前缀 - 实现 `FeynmanReferenceValidator`: - URL 检测(所有文本字段 + summary 独立检查) - Email 检测(PII 泄露防护) - 签名预留 `_snapshot?` 参数(未来扩展引用范围验证) - 更新 `AiJobModule`:注册 FeynmanExecutor + FeynmanBusinessValidator + FeynmanReferenceValidator ### 验证链 ``` 模型原始输出 → AiGatewayService.parseJson() (JSON Repair + Zod Schema) → FeynmanBusinessValidator.validate() → FeynmanReferenceValidator.validate() → 返回 validatedOutput ``` ### 修改文件 - `src/modules/ai-job/feynman-executor.ts`(新增,88 行) - `src/modules/ai-job/feynman-validator.ts`(新增,225 行) - `src/modules/ai-job/feynman-executor.spec.ts`(新增,315 行) - `src/modules/ai-job/ai-job.module.ts`(修改,+7 行:4 imports + 3 providers) ### 代码证据 - `feynman-executor.ts:43-79` — execute() 核心逻辑(消息构造 + AiGateway 调用 + timeout 传递) - `feynman-validator.ts:105-172` — BusinessValidator.validate()(11 项完整验证规则) - `feynman-validator.ts:207-247` — ReferenceValidator.validate()(URL/Email 检测) - `feynman-validator.ts:179-198` — validateStringArray()(数组字段通用验证) - `feynman-executor.ts:2-4` — 仅注入 AiGatewayService(不注入 PrismaService — 零 DB 副作用) ### 测试情况 - 已运行命令: - `npx jest --testPathPatterns="feynman-executor"` - `npx jest --testPathPatterns="ai-job"` - 结果: - 新增 29 tests:Executor(4) + BusinessValidator(18) + ReferenceValidator(3) + 结构验证(4) - 全部通过:15 suites, 310 passed, 18 skipped, 0 failed - TypeScript 编译:新文件零错误 ### 与 Legacy 的兼容性 - 消息构造逻辑与 `FeynmanEvaluationWorkflow.execute()` (workflow.ts:18-29) 一致 - promptKey/promptVersion/outputSchema 与 Legacy 完全相同 - 消息格式:`【知识点标题】+ title + 【知识点原文】+ content + 【用户的费曼解释】+ explanation` - modelTier 使用 Snapshot 中 Definition 指定的 tier(与 Legacy 一致为 `primary`) ### 未完成 / 风险 - Executor 未在 `AiJobExecutionEngine` 中接入(留待 M-AI-05-05 入口路由 + Engine 分派) - Projector 留待 M-AI-05-04 实现 - Engine 中需要增加 `feynman_evaluation` 的 jobType 分支(或改为通用 Registry 驱动的 Executor 分派) ### 是否建议进入 Review - 是 — Executor + 验证链已完成,建议审核后启动 M-AI-05-04
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wangdl/api-server#306
No description provided.