feat: add chat verifier agent
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
# ISS-003 Executor 域级检索水位控制(Phase 2)
|
||||
|
||||
**状态**:待规划
|
||||
**严重程度**:低(当前软约束已从 20+ 次收敛到 10 次,文档级去重兜住无效调用)
|
||||
**发现时间**:2026-07-01
|
||||
**关联**:ISS-002(Part A 软约束已修,LLM 遵守度不够)
|
||||
|
||||
---
|
||||
|
||||
## 现象
|
||||
|
||||
ISS-002 修复后,lookup_knowledge 调用从 20+ 次降到 10 次,但仍有 8 次冗余调用:
|
||||
|
||||
```
|
||||
id=138 → infrastructure 首次检索 HIGHLY_RELEVANT
|
||||
id=139 → infrastructure 变体 → doc_retrieved
|
||||
id=140 → infrastructure 变体 → doc_retrieved
|
||||
id=141 → api 首次检索 REFERENCE
|
||||
id=142 → api 变体 → doc_retrieved
|
||||
id=143 → infrastructure 变体 → doc_retrieved(又跳回)
|
||||
id=144-146 → infrastructure 变体 × 3 → doc_retrieved
|
||||
id=147 → api 变体 → doc_retrieved
|
||||
```
|
||||
|
||||
LLM 在两个域之间反复横跳,prompt 第 2 条"禁止换关键词重新检索"被忽略。
|
||||
|
||||
---
|
||||
|
||||
## 根本原因
|
||||
|
||||
Prompt 软约束依赖 LLM 遵守,但 LLM 在自主决策(ReactAgent)模式下倾向于"多确认一步"而不是"相信已有信息"。
|
||||
|
||||
---
|
||||
|
||||
## 影响
|
||||
|
||||
- **可接受**:文档级去重已拦截重复内容,不影响回答质量
|
||||
- **可优化**:每次冗余调用浪费 400-500ms 服务端检索时间
|
||||
- **长会话风险**:如果 session 持续追问,冗余调用会线性增长
|
||||
|
||||
---
|
||||
|
||||
## 方案:质量等级×水位决策矩阵
|
||||
|
||||
### 核心思路
|
||||
|
||||
将检索决策权从 LLM 思维链移交到代码层,动态判断是否允许下一次 `lookup_knowledge`。
|
||||
|
||||
### 决策矩阵
|
||||
|
||||
```
|
||||
水位
|
||||
低 中 高
|
||||
PRECISE 可用 可用 可用/停
|
||||
HIGHLY_ 可用 可用 停
|
||||
REFERENCE 可定向补 可定向补 停
|
||||
DEDUPED 停 停 停
|
||||
```
|
||||
|
||||
### 水位指标
|
||||
|
||||
| 水位 | 指标 | 说明 |
|
||||
|------|------|------|
|
||||
| 低 | lookup_knowledge 调用 ≤ 3 次 | 检索预算充足 |
|
||||
| 中 | lookup_knowledge 调用 4-8 次 | 适当收紧定向补充 |
|
||||
| 高 | lookup_knowledge 调用 ≥ 8 次 | 熔断,禁止再查 |
|
||||
|
||||
备选水位指标:
|
||||
- Token 消耗量
|
||||
- 已检索域数(retrievedDomainsThisSession.size())
|
||||
|
||||
### 熔断 prompt 示例
|
||||
|
||||
每次工具返回后,代码根据矩阵结果动态拼装约束注入下一步 LLM:
|
||||
|
||||
| 场景 | 熔断 prompt |
|
||||
|------|------------|
|
||||
| 水位高 + HIGHLY_RELEVANT | "水位已高,请直接给出最终结论,不要再调用 lookup_knowledge" |
|
||||
| 水位高 + REFERENCE | "水位已高,lookup_knowledge 已被限制,直接基于已有信息回答" |
|
||||
| 水位低 + REFERENCE | "水位充足,可针对缺少的维度定向补充检索一次" |
|
||||
| DEDUPED + 任何水位 | "该内容已检索过,禁止重复调用 lookup_knowledge" |
|
||||
|
||||
### 架构改动
|
||||
|
||||
```
|
||||
ChatService / ChatExecutorAgent 执行循环
|
||||
│
|
||||
├─ step N: LLM 调用工具 → lookup_knowledge 返回
|
||||
├─ step N+1:
|
||||
│ ├─ 读取 LookupResult(relevanceLevel + retrievedDomainsThisSession)
|
||||
│ ├─ 算当前水位(调用计数 / token / 域数)
|
||||
│ ├─ 查决策矩阵 → 是否允许继续检索
|
||||
│ └─ 拼装熔断 prompt → 注入 LLM 下一步 SystemMessage
|
||||
├─ step N+2: LLM 收到约束后的回复
|
||||
└─ ...
|
||||
```
|
||||
|
||||
### 与现有机制的关系
|
||||
|
||||
| 机制 | 层 | ISS-002 | ISS-003 |
|
||||
|------|-----|---------|---------|
|
||||
| 静态 Prompt 约束 | Prompt | 已实现 | 保留作为基线 |
|
||||
| 行动记忆(retrievedDomainsThisSession) | 工具返回值 | 已实现 | 复用 |
|
||||
| 归一化质量等级(relevanceLevel) | 工具返回值 | 已实现 | 复用 |
|
||||
| 文档级去重(doc_retrieved) | 工具层 | 已实现 | 保留 |
|
||||
| **域级水位决策矩阵** | 代码层 | — | **新增** |
|
||||
| DEDUPED 等级启用 | 工具返回值 | 设计预留 | 启用 |
|
||||
|
||||
---
|
||||
|
||||
## 修法方向
|
||||
|
||||
### 方案 A:决策矩阵(推荐)
|
||||
|
||||
上述质量等级×水位矩阵,在 ChatService 执行循环中做决策。
|
||||
|
||||
优点:
|
||||
- 不依赖 LLM 遵守程度
|
||||
- 保留定向补充的合法通道(比硬拦截更灵活)
|
||||
- 水位指标可配置,运维友好
|
||||
|
||||
缺点:
|
||||
- 需要改动 ChatService/ExecutorAgent 执行逻辑
|
||||
- 需要定义水位阈值(需实测校准)
|
||||
|
||||
### 方案 B:域级工具层硬限流
|
||||
|
||||
在 `LookupKnowledgeTool` 入口直接判断 `isDomainRetrieved(sessionId, domain)`,同域直接返回不检索。
|
||||
|
||||
优点:实现简单,100% 可靠
|
||||
缺点:没有"定向补充"的灵活度,误杀合法跨域查询
|
||||
|
||||
### 建议
|
||||
|
||||
**方案 A**。利用 ISS-002 已有数据结构和归一化等级,新增决策引擎层,改动量不大且灵活度高。
|
||||
|
||||
---
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `src/main/java/com/superbiz/agent/dto/LookupResult.java`
|
||||
- `src/main/java/com/superbiz/agent/tool/RetrievedDocTracker.java`
|
||||
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||
- `src/main/resources/prompts/chat-executor-prompt.md`
|
||||
- 架构设计:`mvp/architecture/action-memory-relevance.md`
|
||||
- OpenSpec:`openspec/changes/archive/2026-07-01-executor-action-memory-relevance/`
|
||||
Reference in New Issue
Block a user