feat(harness,rag): dual LLM audit fields, run conclusion, and hybrid quality
Persist provider reasoning and assistant text separately on agent_reasoning_audit (DeepSeekAssistantMessage path), extract diagnosis_run.conclusion, enrich RAG tool audit (step_id/query/qualityScore), gate empty mysql tools, drop devtools, and align MVP docs after live E2E verification.
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
# Agent 推理审计表:agent_reasoning_audit
|
||||
|
||||
**状态**:当前独立敏感审计表;治理待 ISS-015 收敛
|
||||
**来源**:`V015__create_agent_reasoning_audit.sql`、`AgentReasoningAudit`
|
||||
**状态**:当前独立敏感审计表;治理待 ISS-015 收敛
|
||||
**来源**:`V015__create_agent_reasoning_audit.sql`、`V017__add_content_source_to_agent_reasoning_audit.sql`、`AgentReasoningAudit`、`HarnessAgentAuditHook`
|
||||
|
||||
## 定位
|
||||
|
||||
`agent_reasoning_audit` 保存模型 Provider 在 Agent 步骤 metadata 中实际返回的 reasoning 内容。它与普通 Trace、AgentStep、Evidence Snapshot 和业务发布结果物理分离,不能作为事实证据或诊断结论来源。
|
||||
`agent_reasoning_audit` 按 **Diagnosis Agent 每个模型步骤** 保存两类 LLM 面向文本,并与普通 Trace、AgentStep、Evidence Snapshot、业务发布结果物理分离:
|
||||
|
||||
Provider 未返回 reasoning 时仍写入 unavailable 记录,防止把“没有返回”误判为“审计链路漏写”。系统不得从最终回答、Tool 调用或其他字段生成伪 reasoning。
|
||||
1. **Provider reasoning / thinking**(`reasoning_content`)
|
||||
2. **Assistant 可见正文**(`assistant_text`:最终 prose 和/或 tool-call **计划**)
|
||||
|
||||
它不能作为事实证据或诊断结论来源。Tool **结果**载荷不进本表(见 `tool_invocation`)。
|
||||
|
||||
Provider 未返回 reasoning 时仍写入记录(`reasoning_available=false`),防止把“没有返回”误判为“审计链路漏写”。系统不得从最终回答、Tool 调用或其他字段生成伪 reasoning。
|
||||
|
||||
## 字段
|
||||
|
||||
@@ -19,8 +24,10 @@ Provider 未返回 reasoning 时仍写入 unavailable 记录,防止把“没
|
||||
| `step_index` | INT | 是 | Agent 模型步骤序号 |
|
||||
| `agent_name` | VARCHAR(64) | 是 | Agent 身份,当前为 `diagnosis_agent` |
|
||||
| `reasoning_available` | BOOLEAN | 是 | Provider 是否实际返回非空 reasoning |
|
||||
| `reasoning_content` | LONGTEXT | 否 | Provider reasoning 原文;Hook 当前最多保留 32000 个字符 |
|
||||
| `content_bytes` | INT | 是 | 截断后 reasoning 的 UTF-8 字节数;unavailable 时为 0 |
|
||||
| `reasoning_content` | LONGTEXT | 否 | Provider CoT / thinking 原文;Hook 单字段最多保留 32000 字符 |
|
||||
| `assistant_text` | LONGTEXT | 否 | 本步 assistant 可见正文;若有 tool_call,可附带 `tool_calls:` 计划预览(**不含** tool 结果) |
|
||||
| `content_source` | VARCHAR(64) | 否 | 本步写入摘要:`PROVIDER_REASONING+ASSISTANT_TEXT` / `PROVIDER_REASONING` / `ASSISTANT_TEXT` / `TOOL_CALL_PLAN` / `NONE` |
|
||||
| `content_bytes` | INT | 是 | 截断后 `reasoning_content` + `assistant_text` 的 UTF-8 字节合计 |
|
||||
| `created_at` | DATETIME | 是 | 创建时间,默认当前时间 |
|
||||
|
||||
## 索引
|
||||
@@ -36,15 +43,36 @@ Provider 未返回 reasoning 时仍写入 unavailable 记录,防止把“没
|
||||
- `session_id` 逻辑关联 `chat_session.session_id`。
|
||||
- 通过 `session_id + run_id + step_index` 与 `agent_step` 逻辑对应,不建立数据库外键。
|
||||
|
||||
## 写入规则
|
||||
## 写入规则(HarnessAgentAuditHook)
|
||||
|
||||
- Provider 返回非空 reasoning:`reasoning_available=true`,保存截断后的原文及实际 UTF-8 字节数。
|
||||
- Provider 未返回 reasoning:`reasoning_available=false`,`reasoning_content=NULL`,`content_bytes=0`。
|
||||
- `agent_step.thought` 继续保持为空;普通 Trace 仅保留 availability/bytes metadata。
|
||||
- Reasoning 不进入 SSE、PreviousTurn、Evidence Snapshot、发布结果或应用日志。
|
||||
### 捕获来源(按优先级)
|
||||
|
||||
1. **DeepSeek 生产主路径**:`DeepSeekAssistantMessage.getReasoningContent()`
|
||||
(Spring AI 将 API 的 `message.reasoning_content` 映射到该专用字段,**不是** `AssistantMessage.metadata`)
|
||||
2. 反射 `getReasoningContent()`(兼容序列化/子类)
|
||||
3. metadata 键兜底:`reasoning_content` / `reasoningContent` / `reasoning` / `thinking` / `reasoning_text` / `reasoningText`(单测与其它 Provider)
|
||||
|
||||
`assistant_text` 来自 `AssistantMessage.getText()`;若本步有 tool_calls,追加有界的 `tool_calls:` 名称与 args 预览。
|
||||
|
||||
### 落库语义
|
||||
|
||||
- 有 Provider reasoning:`reasoning_available=true`,写入截断后的 `reasoning_content`。
|
||||
- 无 Provider reasoning:`reasoning_available=false`,`reasoning_content=NULL`;仍可写入 `assistant_text`。
|
||||
- `content_source` 反映本步实际写入组合;两者皆空则为 `NONE`。
|
||||
- `content_bytes` 为两列截断后文本 UTF-8 字节之和。
|
||||
- **禁止**把 tool 执行结果、raw Tool response、用户 Prompt 全文写入本表。
|
||||
|
||||
### 与其它表的边界
|
||||
|
||||
- 普通 Trace / Timeline 只暴露 `reasoning_available`、`reasoning_bytes` / `assistant_bytes`、`content_source` 等有界 metadata,不返回 reasoning/assistant 原文。
|
||||
- `agent_step.model_input` / `model_output` 仍为有界 metadata。
|
||||
- `agent_step.thought` 可作为兼容镜像:优先 Provider reasoning,否则 assistant 正文;完整双字段以本表为准。
|
||||
- Reasoning / assistant 审计原文不进入 SSE、PreviousTurn、Evidence Snapshot、发布结果或应用日志。
|
||||
|
||||
## 查询与治理
|
||||
|
||||
当前独立接口为 `GET /api/diagnosis/{sessionId}/trace/reasoning?runId={runId}`。`runId` 必填,服务端校验其属于 path `sessionId`,并按 `step_index` 返回记录。
|
||||
当前独立接口为 `GET /api/diagnosis/{sessionId}/trace/reasoning?runId={runId}`。`runId` 必填,服务端校验其属于 path `sessionId`,并按 `step_index` 返回记录(含 `reasoningContent`、`assistantText`、`contentSource`)。
|
||||
|
||||
分表和归属校验已经实现,但不能等同于完整安全治理。身份认证、角色授权、保留/删除期限、静态与传输加密以及真实 Provider/V015 验证仍由 ISS-015 阶段 3 跟踪;治理完成前不应将该接口暴露给普通业务用户。
|
||||
**已验证(2026-07-28 live E2E,DeepSeek `deepseek-v4-flash`)**:thinking 模式下两步模型调用均可得到 `reasoning_available=true` 且 `content_source=PROVIDER_REASONING+ASSISTANT_TEXT`。
|
||||
|
||||
分表和归属校验已经实现,但不能等同于完整安全治理。身份认证、角色授权、保留/删除期限、静态与传输加密仍由 ISS-015 跟踪;治理完成前不应将该接口暴露给普通业务用户。
|
||||
|
||||
Reference in New Issue
Block a user