Compare commits
2
Commits
246c99b954
...
2609c5a5ab
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2609c5a5ab | ||
|
|
bf5286c8f4 |
@@ -0,0 +1,59 @@
|
|||||||
|
# SuperBizAgent Interview Guide
|
||||||
|
|
||||||
|
## 一句话定位
|
||||||
|
|
||||||
|
SuperBizAgent 是一个面向企业故障诊断场景的 Agent Engineering 项目:它把用户问题或告警事件转成可追踪的多 Agent 执行链路,并把工具证据、模型步骤、最终答案和反馈统一落到诊断 trace 中。
|
||||||
|
|
||||||
|
## 面试重点
|
||||||
|
|
||||||
|
- **多 Agent 编排**:普通 Chat 的复杂问题走 `Planner -> Executor -> Verifier`;AIOps 告警入口走 Supervisor 调度 Planner/Executor。
|
||||||
|
- **工具证据链**:知识库、日志、指标和 Prometheus 告警都通过工具调用进入链路,并记录到 `tool_invocation`。
|
||||||
|
- **可追踪诊断**:一次会话对应一个 `sessionId`,最终可以通过 `GET /api/diagnosis/{sessionId}/trace` 回放。
|
||||||
|
- **质量门**:Chat 链路包含 Verifier,把 groundedness、facts checked 和 evidence refs 写回 `diagnosis_session.self_evaluation`。
|
||||||
|
- **AIOps 产品边界**:有告警 payload 时聚焦该告警;没有 payload 时先自动发现 active alerts。
|
||||||
|
- **可复现 Demo**:`mvp-demo` profile 使用 mock Prometheus 和 mock CLS,让面试演示不依赖真实线上故障。
|
||||||
|
|
||||||
|
## 推荐阅读顺序
|
||||||
|
|
||||||
|
1. `interview/demo-script.md`:面试现场怎么讲、怎么演示。
|
||||||
|
2. `interview/architecture.md`:系统架构和两条主链路。
|
||||||
|
3. `interview/design-tradeoffs.md`:关键设计取舍和可被追问的问题。
|
||||||
|
4. `interview/acceptance-checklist.md`:面试前验证清单。
|
||||||
|
5. `mvp/demo/README.md`:更细的 MVP 可执行 runbook。
|
||||||
|
|
||||||
|
## 核心 Demo
|
||||||
|
|
||||||
|
### Chat Diagnosis
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /api/chat
|
||||||
|
-> ChatService.executeChatWithStrategy(...)
|
||||||
|
-> simple ReactAgent or Planner -> Executor -> Verifier
|
||||||
|
-> lookup_knowledge / query_logs / query_metrics
|
||||||
|
-> diagnosis_session + agent_step + tool_invocation
|
||||||
|
-> GET /api/diagnosis/{sessionId}/trace
|
||||||
|
```
|
||||||
|
|
||||||
|
### AIOps Alert Diagnosis
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /api/ai_ops
|
||||||
|
-> AiOpsService.executeAiOpsAnalysis(...)
|
||||||
|
-> ai_ops_supervisor
|
||||||
|
-> planner_agent / executor_agent
|
||||||
|
-> queryPrometheusAlerts + logs + knowledge
|
||||||
|
-> scoped alert report
|
||||||
|
-> GET /api/diagnosis/{sessionId}/trace
|
||||||
|
```
|
||||||
|
|
||||||
|
## 当前完成度
|
||||||
|
|
||||||
|
- Chat 诊断链路:可运行、可追踪、有 Verifier。
|
||||||
|
- AIOps 告警链路:可运行、可追踪、支持 payload scope control。
|
||||||
|
- Trace API:统一返回 session、agent steps、tool invocations 和 summary。
|
||||||
|
- Demo 文档:`mvp/demo/README.md` 和 `mvp/demo/aiops-alert-acceptance.md`。
|
||||||
|
- Devflow 沉淀:`devflow/index.md` 记录了 MVP、Verifier、AIOps trace 和 AIOps scope-control 的演进。
|
||||||
|
|
||||||
|
## 面试时的主叙事
|
||||||
|
|
||||||
|
这个项目不是简单调用大模型,而是在做一个可审计的 Agent 诊断系统。核心价值是:模型可以规划和推理,但每一步工具证据、最终结论和质量评估都能被 trace API 回放。面试时重点展示“从问题到证据到答案到验证”的完整闭环。
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
# Acceptance Checklist
|
||||||
|
|
||||||
|
## 面试前环境检查
|
||||||
|
|
||||||
|
- 当前分支包含最新 AIOps trace/scope 变更。
|
||||||
|
- MySQL 可连接。
|
||||||
|
- Redis 可连接。
|
||||||
|
- Milvus/Zilliz 可连接。
|
||||||
|
- 模型 API key 可用。
|
||||||
|
- `mvp-demo` profile 开启 mock Prometheus 和 mock CLS。
|
||||||
|
|
||||||
|
启动:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
mvn spring-boot:run "-Dspring-boot.run.profiles=mvp-demo"
|
||||||
|
```
|
||||||
|
|
||||||
|
编译检查:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
mvn -q -DskipTests compile
|
||||||
|
```
|
||||||
|
|
||||||
|
目标测试:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
mvn -q "-Dtest=AiOpsServiceTest,ChatServiceSequentialAgentTest,DiagnosisTraceServiceTest" test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Chat Demo 验收
|
||||||
|
|
||||||
|
请求:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$sessionId = "interview-chat-payment-timeout-001"
|
||||||
|
$body = @{
|
||||||
|
Id = $sessionId
|
||||||
|
Question = "支付接口最近出现超时,请结合知识库、日志和指标判断可能原因,并给出修复建议。"
|
||||||
|
} | ConvertTo-Json
|
||||||
|
|
||||||
|
Invoke-RestMethod `
|
||||||
|
-Method Post `
|
||||||
|
-Uri "http://localhost:9900/api/chat" `
|
||||||
|
-ContentType "application/json" `
|
||||||
|
-Body $body
|
||||||
|
```
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 返回 `data.success = true`。
|
||||||
|
- 返回 `data.sessionId = interview-chat-payment-timeout-001`。
|
||||||
|
- `diagnosis_session.agent_flow = CHAT`。
|
||||||
|
- trace API 返回 session、steps、toolInvocations。
|
||||||
|
- 复杂问题下 trace 中能看到 verifier 相关数据。
|
||||||
|
|
||||||
|
SQL:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts/query_mysql.py "SELECT session_id, agent_flow, status, step_count, tool_call_count FROM diagnosis_session WHERE session_id='interview-chat-payment-timeout-001'"
|
||||||
|
```
|
||||||
|
|
||||||
|
## AIOps Demo 验收
|
||||||
|
|
||||||
|
请求:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$aiopsSessionId = "interview-aiops-payment-cpu-001"
|
||||||
|
$aiopsBody = @{
|
||||||
|
sessionId = $aiopsSessionId
|
||||||
|
alertName = "HighCPUUsage"
|
||||||
|
service = "payment-service"
|
||||||
|
severity = "P1"
|
||||||
|
description = "服务 payment-service 的 CPU 使用率持续超过 80%,当前值为 92%。实例: pod-payment-service-7d8f9c6b5-x2k4m。"
|
||||||
|
timeRange = "last_15m"
|
||||||
|
userRequest = "请结合 Prometheus 活动告警、system-metrics 日志和知识库生成告警分析报告。"
|
||||||
|
} | ConvertTo-Json
|
||||||
|
|
||||||
|
Invoke-WebRequest `
|
||||||
|
-Method Post `
|
||||||
|
-Uri "http://localhost:9900/api/ai_ops" `
|
||||||
|
-ContentType "application/json" `
|
||||||
|
-Body $aiopsBody
|
||||||
|
```
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- SSE 首条包含 `type=session`。
|
||||||
|
- SSE 最后包含 `type=done`。
|
||||||
|
- `diagnosis_session.agent_flow = AI_OPS`。
|
||||||
|
- `diagnosis_session.status = SUCCESS`。
|
||||||
|
- `diagnosis_session.answer` 有最终报告。
|
||||||
|
- trace API 返回 AIOps steps 和 tool invocations。
|
||||||
|
- 报告主章节聚焦 `HighCPUUsage/payment-service`。
|
||||||
|
- 无 `告警根因分析 - HighMemoryUsage` 独立章节。
|
||||||
|
- 无 `告警根因分析 - SlowResponse` 独立章节。
|
||||||
|
- 有“相关风险告警”或类似上下文说明。
|
||||||
|
|
||||||
|
SQL:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts/query_mysql.py "SELECT session_id, agent_flow, status, total_duration_ms, step_count, tool_call_count FROM diagnosis_session WHERE session_id='interview-aiops-payment-cpu-001'"
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts/query_mysql.py "SELECT tool_name, COUNT(*) AS cnt FROM tool_invocation WHERE session_id='interview-aiops-payment-cpu-001' GROUP BY tool_name ORDER BY tool_name"
|
||||||
|
```
|
||||||
|
|
||||||
|
Scope 检查:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts/query_mysql.py "SELECT (answer LIKE '%告警根因分析 - HighCPUUsage%') AS has_main_root_cause, (answer LIKE '%告警根因分析 - HighMemoryUsage%') AS has_memory_root_cause, (answer LIKE '%告警根因分析 - SlowResponse%') AS has_slow_root_cause, (answer LIKE '%相关风险告警%') AS has_related_risk FROM diagnosis_session WHERE session_id='interview-aiops-payment-cpu-001'"
|
||||||
|
```
|
||||||
|
|
||||||
|
期望:
|
||||||
|
|
||||||
|
```text
|
||||||
|
has_main_root_cause = 1
|
||||||
|
has_memory_root_cause = 0
|
||||||
|
has_slow_root_cause = 0
|
||||||
|
has_related_risk = 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Trace API 验收
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Invoke-RestMethod `
|
||||||
|
-Method Get `
|
||||||
|
-Uri "http://localhost:9900/api/diagnosis/interview-aiops-payment-cpu-001/trace"
|
||||||
|
```
|
||||||
|
|
||||||
|
若 PowerShell 对长 JSON 或特殊字符不稳定,可以用:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl.exe --silent --show-error --max-time 60 "http://localhost:9900/api/diagnosis/interview-aiops-payment-cpu-001/trace"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### MySQL stale connection
|
||||||
|
|
||||||
|
现象:
|
||||||
|
|
||||||
|
```text
|
||||||
|
HikariPool - Connection is not available
|
||||||
|
No operations allowed after connection closed
|
||||||
|
```
|
||||||
|
|
||||||
|
当前已在 `application.yml` 配置:
|
||||||
|
|
||||||
|
- `maximum-pool-size: 5`
|
||||||
|
- `minimum-idle: 1`
|
||||||
|
- `connection-timeout: 10000`
|
||||||
|
- `validation-timeout: 5000`
|
||||||
|
- `idle-timeout: 60000`
|
||||||
|
- `max-lifetime: 120000`
|
||||||
|
- `keepalive-time: 30000`
|
||||||
|
|
||||||
|
处理:
|
||||||
|
|
||||||
|
- 重新编译或重启服务。
|
||||||
|
- 确认日志中新的 HikariPool 启动成功。
|
||||||
|
- 再跑 trace 或 AIOps 请求。
|
||||||
|
|
||||||
|
### SSE 客户端显示异常
|
||||||
|
|
||||||
|
PowerShell `Invoke-WebRequest` 有时对 SSE 或长 JSON 处理不稳定。可以改用 `curl.exe` 或直接查询 MySQL 和 trace API 验证结果。
|
||||||
|
|
||||||
|
### OpenSpec 全量校验失败
|
||||||
|
|
||||||
|
`openspec validate --all --strict` 可能因为历史未完成 change 失败。面试材料主要依赖已归档的 AIOps spec 和 MVP trace spec,可以单独验证相关 spec。
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
# Architecture
|
||||||
|
|
||||||
|
## 系统分层
|
||||||
|
|
||||||
|
```text
|
||||||
|
API Layer
|
||||||
|
-> ChatController / DiagnosisTraceController
|
||||||
|
|
||||||
|
Agent Orchestration
|
||||||
|
-> ChatService / AiOpsService
|
||||||
|
|
||||||
|
Tools
|
||||||
|
-> lookupKnowledgeTool / queryLogs / queryMetrics / queryPrometheusAlerts
|
||||||
|
|
||||||
|
Persistence
|
||||||
|
-> diagnosis_session / agent_step / tool_invocation
|
||||||
|
|
||||||
|
Trace
|
||||||
|
-> GET /api/diagnosis/{sessionId}/trace
|
||||||
|
```
|
||||||
|
|
||||||
|
## Chat 链路
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
User[User Question] --> ChatAPI[POST /api/chat]
|
||||||
|
ChatAPI --> Strategy[ChatService.executeChatWithStrategy]
|
||||||
|
Strategy --> Complexity{QuestionComplexity}
|
||||||
|
Complexity -->|simple| Single[ReactAgent]
|
||||||
|
Complexity -->|complex| Planner[Planner Agent]
|
||||||
|
Planner --> Executor[Executor Agent]
|
||||||
|
Executor --> Tools[Evidence Tools]
|
||||||
|
Tools --> Executor
|
||||||
|
Executor --> Verifier[Verifier Agent]
|
||||||
|
Verifier --> Answer[Final Answer]
|
||||||
|
Answer --> Session[diagnosis_session]
|
||||||
|
Planner --> Steps[agent_step]
|
||||||
|
Executor --> Steps
|
||||||
|
Verifier --> Steps
|
||||||
|
Tools --> Invocations[tool_invocation]
|
||||||
|
Session --> Trace[GET /api/diagnosis/{sessionId}/trace]
|
||||||
|
Steps --> Trace
|
||||||
|
Invocations --> Trace
|
||||||
|
```
|
||||||
|
|
||||||
|
关键代码:
|
||||||
|
|
||||||
|
- `ChatController.chat(...)`
|
||||||
|
- `ChatService.executeChatWithStrategy(...)`
|
||||||
|
- `ChatService.executeChatComplex(...)`
|
||||||
|
- `AgentLoggingHook`
|
||||||
|
- `ToolInvocationRecorder`
|
||||||
|
- `DiagnosisTraceService.getTrace(...)`
|
||||||
|
|
||||||
|
## AIOps 链路
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
Alert[Alert Payload or Empty Request] --> AiOpsAPI[POST /api/ai_ops]
|
||||||
|
AiOpsAPI --> SessionEvent[SSE session event]
|
||||||
|
AiOpsAPI --> AiOpsService[AiOpsService.executeAiOpsAnalysis]
|
||||||
|
AiOpsService --> PromptMode{Payload?}
|
||||||
|
PromptMode -->|yes| Targeted[PAYLOAD_TARGETED]
|
||||||
|
PromptMode -->|no| Discovery[AUTO_DISCOVERY]
|
||||||
|
Targeted --> Supervisor[ai_ops_supervisor]
|
||||||
|
Discovery --> Supervisor
|
||||||
|
Supervisor --> Planner[planner_agent]
|
||||||
|
Supervisor --> Executor[executor_agent]
|
||||||
|
Planner --> Tools[Prometheus / Logs / Knowledge]
|
||||||
|
Executor --> Tools
|
||||||
|
Tools --> Report[Alert Report]
|
||||||
|
Report --> Persist[diagnosis_session.answer]
|
||||||
|
Planner --> Steps[agent_step]
|
||||||
|
Executor --> Steps
|
||||||
|
Tools --> Invocations[tool_invocation]
|
||||||
|
Persist --> Trace[GET /api/diagnosis/{sessionId}/trace]
|
||||||
|
Steps --> Trace
|
||||||
|
Invocations --> Trace
|
||||||
|
```
|
||||||
|
|
||||||
|
关键代码:
|
||||||
|
|
||||||
|
- `ChatController.aiOps(...)`
|
||||||
|
- `AIOpsRequest`
|
||||||
|
- `AiOpsService.resolveSessionId(...)`
|
||||||
|
- `AiOpsService.buildTaskPrompt(...)`
|
||||||
|
- `AiOpsService.hasAlertPayload(...)`
|
||||||
|
- `AiOpsService.persistFinalReport(...)`
|
||||||
|
|
||||||
|
## Trace 数据模型
|
||||||
|
|
||||||
|
### `diagnosis_session`
|
||||||
|
|
||||||
|
记录一次诊断会话的主信息:
|
||||||
|
|
||||||
|
- `session_id`
|
||||||
|
- `query`
|
||||||
|
- `status`
|
||||||
|
- `agent_flow`
|
||||||
|
- `total_duration_ms`
|
||||||
|
- `total_token_count`
|
||||||
|
- `step_count`
|
||||||
|
- `tool_call_count`
|
||||||
|
- `answer`
|
||||||
|
- `self_evaluation`
|
||||||
|
- `feedback`
|
||||||
|
|
||||||
|
### `agent_step`
|
||||||
|
|
||||||
|
记录 Agent 模型调用过程:
|
||||||
|
|
||||||
|
- `session_id`
|
||||||
|
- `step_index`
|
||||||
|
- `agent_name`
|
||||||
|
- `model_input`
|
||||||
|
- `model_output`
|
||||||
|
- `thought`
|
||||||
|
- `has_tool_call`
|
||||||
|
- `duration_ms`
|
||||||
|
- `token_count`
|
||||||
|
|
||||||
|
### `tool_invocation`
|
||||||
|
|
||||||
|
记录真实工具调用:
|
||||||
|
|
||||||
|
- `session_id`
|
||||||
|
- `tool_name`
|
||||||
|
- `input_params`
|
||||||
|
- `output_preview`
|
||||||
|
- `output_length`
|
||||||
|
- `retrieval_layer`
|
||||||
|
- `relevance_level`
|
||||||
|
- `duration_ms`
|
||||||
|
- `success`
|
||||||
|
- `error_message`
|
||||||
|
|
||||||
|
## 为什么 trace 是核心
|
||||||
|
|
||||||
|
Agent 系统的风险不只是“答案错”,还包括“答案看起来对但无法解释”。这个项目把执行链路拆成 session、step、tool 三层,让面试官可以看到:
|
||||||
|
|
||||||
|
- 模型为什么这么答
|
||||||
|
- 调了哪些工具
|
||||||
|
- 工具返回了什么证据
|
||||||
|
- Verifier 如何判断答案可信度
|
||||||
|
- 用户反馈如何回写到同一个 session
|
||||||
|
|
||||||
|
这就是项目区别于普通 Chatbot 的地方。
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
# Interview Demo Script
|
||||||
|
|
||||||
|
## 30 秒开场
|
||||||
|
|
||||||
|
这是一个 Agent Engineering 项目,场景是企业故障诊断。它支持两类入口:用户主动提问的 Chat 诊断,以及告警事件驱动的 AIOps 诊断。项目重点不是单次回答,而是把多 Agent 执行、工具证据、Verifier 评估、最终报告和反馈都沉淀成可回放的 trace。
|
||||||
|
|
||||||
|
## Demo 准备
|
||||||
|
|
||||||
|
启动服务:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
mvn spring-boot:run "-Dspring-boot.run.profiles=mvp-demo"
|
||||||
|
```
|
||||||
|
|
||||||
|
确认服务地址:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://localhost:9900
|
||||||
|
```
|
||||||
|
|
||||||
|
`mvp-demo` profile 下:
|
||||||
|
|
||||||
|
- Prometheus 告警使用 mock 数据。
|
||||||
|
- CLS 日志使用 mock 数据。
|
||||||
|
- MySQL、Redis、Milvus/Zilliz 和模型配置仍使用当前项目配置。
|
||||||
|
|
||||||
|
## Demo 1: Chat 诊断
|
||||||
|
|
||||||
|
目标:展示普通用户问题如何进入多 Agent 诊断、调用工具、经过 Verifier,并生成 trace。
|
||||||
|
|
||||||
|
请求:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$sessionId = "interview-chat-payment-timeout-001"
|
||||||
|
$body = @{
|
||||||
|
Id = $sessionId
|
||||||
|
Question = "支付接口最近出现超时,请结合知识库、日志和指标判断可能原因,并给出修复建议。"
|
||||||
|
} | ConvertTo-Json
|
||||||
|
|
||||||
|
Invoke-RestMethod `
|
||||||
|
-Method Post `
|
||||||
|
-Uri "http://localhost:9900/api/chat" `
|
||||||
|
-ContentType "application/json" `
|
||||||
|
-Body $body
|
||||||
|
```
|
||||||
|
|
||||||
|
讲解点:
|
||||||
|
|
||||||
|
- `ChatController` 把请求交给 `ChatService.executeChatWithStrategy(...)`。
|
||||||
|
- 简单问题走单 ReactAgent,复杂问题走 `Planner -> Executor -> Verifier`。
|
||||||
|
- Executor 可以调用知识库、日志、指标等工具。
|
||||||
|
- Verifier 会基于工具证据生成 groundedness 评估。
|
||||||
|
- 最终会写入 `diagnosis_session`、`agent_step`、`tool_invocation`。
|
||||||
|
|
||||||
|
查询 trace:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Invoke-RestMethod `
|
||||||
|
-Method Get `
|
||||||
|
-Uri "http://localhost:9900/api/diagnosis/$sessionId/trace"
|
||||||
|
```
|
||||||
|
|
||||||
|
展示点:
|
||||||
|
|
||||||
|
- `data.session.agentFlow = CHAT`
|
||||||
|
- `data.steps` 中能看到 planner/executor/verifier
|
||||||
|
- `data.toolInvocations` 中能看到证据工具
|
||||||
|
- `data.session.selfEvaluation` 中有 verifier 结果
|
||||||
|
|
||||||
|
## Demo 2: AIOps 告警诊断
|
||||||
|
|
||||||
|
目标:展示告警 payload 如何触发 AIOps 入口,并且报告只聚焦目标告警。
|
||||||
|
|
||||||
|
请求:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$aiopsSessionId = "interview-aiops-payment-cpu-001"
|
||||||
|
$aiopsBody = @{
|
||||||
|
sessionId = $aiopsSessionId
|
||||||
|
alertName = "HighCPUUsage"
|
||||||
|
service = "payment-service"
|
||||||
|
severity = "P1"
|
||||||
|
description = "服务 payment-service 的 CPU 使用率持续超过 80%,当前值为 92%。实例: pod-payment-service-7d8f9c6b5-x2k4m。"
|
||||||
|
timeRange = "last_15m"
|
||||||
|
userRequest = "请结合 Prometheus 活动告警、system-metrics 日志和知识库生成告警分析报告。"
|
||||||
|
} | ConvertTo-Json
|
||||||
|
|
||||||
|
Invoke-WebRequest `
|
||||||
|
-Method Post `
|
||||||
|
-Uri "http://localhost:9900/api/ai_ops" `
|
||||||
|
-ContentType "application/json" `
|
||||||
|
-Body $aiopsBody
|
||||||
|
```
|
||||||
|
|
||||||
|
讲解点:
|
||||||
|
|
||||||
|
- `/api/ai_ops` 接受可选 `AIOpsRequest`。
|
||||||
|
- 首条 SSE 消息会返回 `type=session`。
|
||||||
|
- `AiOpsService` 根据 payload 判断模式:
|
||||||
|
- `PAYLOAD_TARGETED`:聚焦传入告警。
|
||||||
|
- `AUTO_DISCOVERY`:没有 payload 时先查 active alerts。
|
||||||
|
- AIOps 暂时不加 Verifier,先保证告警入口、证据工具和 trace 可用。
|
||||||
|
|
||||||
|
查询 trace:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Invoke-RestMethod `
|
||||||
|
-Method Get `
|
||||||
|
-Uri "http://localhost:9900/api/diagnosis/$aiopsSessionId/trace"
|
||||||
|
```
|
||||||
|
|
||||||
|
展示点:
|
||||||
|
|
||||||
|
- `data.session.agentFlow = AI_OPS`
|
||||||
|
- `data.session.answer` 有最终告警报告
|
||||||
|
- `data.toolInvocations` 有 `query_metrics`、`query_logs`、`lookup_knowledge`
|
||||||
|
- 报告有 `HighCPUUsage/payment-service` 的完整根因分析
|
||||||
|
- 其他 active alerts 只作为相关风险出现,不展开成独立根因章节
|
||||||
|
|
||||||
|
## MySQL 验证
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts/query_mysql.py "SELECT session_id, agent_flow, status, step_count, tool_call_count FROM diagnosis_session ORDER BY id DESC LIMIT 5"
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts/query_mysql.py "SELECT tool_name, COUNT(*) AS cnt FROM tool_invocation WHERE session_id='interview-aiops-payment-cpu-001' GROUP BY tool_name"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 收尾总结
|
||||||
|
|
||||||
|
这套 Demo 展示的是一个完整 Agent 系统,而不是一次模型问答:入口有明确场景边界,Agent 负责规划和执行,工具提供证据,Verifier 提供质量门,trace API 提供审计和复盘能力。AIOps 入口进一步证明它可以从用户问答扩展到事件驱动诊断。
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# Design Tradeoffs
|
||||||
|
|
||||||
|
## 1. 为什么要做 trace,而不是只返回答案
|
||||||
|
|
||||||
|
普通 Chatbot 只关注最终回答,但故障诊断更需要可审计性。一次诊断至少要回答三件事:
|
||||||
|
|
||||||
|
- 结论是什么
|
||||||
|
- 证据来自哪里
|
||||||
|
- 哪些步骤由哪个 Agent 完成
|
||||||
|
|
||||||
|
因此项目把一次会话拆成:
|
||||||
|
|
||||||
|
- `diagnosis_session`:会话级摘要、最终答案、质量评估、反馈。
|
||||||
|
- `agent_step`:Agent 模型输入输出、耗时、token 和工具调用标记。
|
||||||
|
- `tool_invocation`:真实工具调用参数、输出预览、成功状态和检索元数据。
|
||||||
|
|
||||||
|
这个设计牺牲了一些实现复杂度,但换来了可回放、可调试、可演示。
|
||||||
|
|
||||||
|
## 2. 为什么 Chat 有 Verifier,AIOps 暂时没有
|
||||||
|
|
||||||
|
Chat 入口的问题更开放,用户可能要求复杂推理或跨领域结论,所以 Verifier 是必要的质量门。当前 Chat 链路通过 `Planner -> Executor -> Verifier` 固定流程,把 groundedness 和 facts checked 写入 `self_evaluation`。
|
||||||
|
|
||||||
|
AIOps 当前阶段先不加 Verifier,原因是:
|
||||||
|
|
||||||
|
- AIOps 刚完成从“自动跑告警”到“可追踪告警入口”的改造。
|
||||||
|
- 先要确认告警 payload、工具证据、最终报告和 trace 能闭环。
|
||||||
|
- AIOps Verifier 的规则不同于 Chat Verifier,需要检查告警 scope、证据覆盖和处置建议,不宜直接复用。
|
||||||
|
|
||||||
|
后续可以做 lightweight AIOps Verifier,检查报告是否聚焦 payload、是否引用工具证据、是否误展开无关告警。
|
||||||
|
|
||||||
|
## 3. 为什么 AIOps payload scope 先用 prompt 控制
|
||||||
|
|
||||||
|
运行验证发现:传入 `HighCPUUsage/payment-service` 后,Agent 仍可能把 mock Prometheus 返回的所有 active alerts 都展开分析。这个问题的本质是任务边界不清晰。
|
||||||
|
|
||||||
|
当前选择 prompt-level scope control:
|
||||||
|
|
||||||
|
- 有 payload:`PAYLOAD_TARGETED`,最终报告围绕传入告警。
|
||||||
|
- 无 payload:`AUTO_DISCOVERY`,先调用 `queryPrometheusAlerts` 自动发现告警。
|
||||||
|
|
||||||
|
没有先做 Java 侧过滤,是因为:
|
||||||
|
|
||||||
|
- 过滤工具结果会降低 Agent 发现关联风险的能力。
|
||||||
|
- 目前需要的是报告主线聚焦,而不是完全屏蔽上下文。
|
||||||
|
- Prompt 改动小,风险低,能保留 Agent 灵活性。
|
||||||
|
|
||||||
|
已验证结果:主报告有 `HighCPUUsage/payment-service` 的完整根因分析,`HighMemoryUsage` 和 `SlowResponse` 只作为相关风险出现。
|
||||||
|
|
||||||
|
## 4. 为什么用 `tool_invocation` 统计真实工具调用次数
|
||||||
|
|
||||||
|
早期可以通过 `agent_step.hasToolCall` 粗略判断是否调用工具,但它统计的是“哪些模型步骤包含工具调用”,不是“真实调用了几次工具”。
|
||||||
|
|
||||||
|
现在 `tool_call_count` 来自:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ToolInvocationRepository.countBySessionId(sessionId)
|
||||||
|
```
|
||||||
|
|
||||||
|
这样更符合 trace 语义:
|
||||||
|
|
||||||
|
- 一个 step 可能调用多个工具。
|
||||||
|
- 工具可能来自不同来源:知识库、日志、指标、Prometheus。
|
||||||
|
- 面试时可以把 `tool_call_count` 和 trace 中返回的工具明细对上。
|
||||||
|
|
||||||
|
## 5. 为什么保留 mock Prometheus 和 mock CLS
|
||||||
|
|
||||||
|
面试 Demo 最怕不稳定。真实 Prometheus、日志平台和线上故障都有不可控因素,所以 MVP profile 保留 mock 工具:
|
||||||
|
|
||||||
|
- `prometheus.mock-enabled=true`
|
||||||
|
- `cls.mock-enabled=true`
|
||||||
|
|
||||||
|
这样可以稳定复现:
|
||||||
|
|
||||||
|
- `HighCPUUsage/payment-service`
|
||||||
|
- `HighMemoryUsage/order-service`
|
||||||
|
- `SlowResponse/user-service`
|
||||||
|
- system-metrics、application-logs、database-slow-query 等日志证据
|
||||||
|
|
||||||
|
这不是逃避真实集成,而是把“Agent 编排和证据追踪”作为面试演示的主目标。
|
||||||
|
|
||||||
|
## 6. 为什么把面试材料单独放 `interview/`
|
||||||
|
|
||||||
|
`mvp/` 是持续迭代现场,包含过程文档、验收记录和 runbook。面试材料的目标不同,它应该是可讲、可演示、可评估的展示层。
|
||||||
|
|
||||||
|
因此:
|
||||||
|
|
||||||
|
- `mvp/` 保留真实演进材料。
|
||||||
|
- `devflow/` 保留决策沉淀。
|
||||||
|
- `interview/` 只组织面试叙事和演示脚本。
|
||||||
|
|
||||||
|
这样后续继续做 AIOps Verifier、UI、更多工具集成时,不会污染面试讲稿。
|
||||||
|
|
||||||
|
## 7. 可以主动承认的限制
|
||||||
|
|
||||||
|
- AIOps 还没有 Verifier。
|
||||||
|
- Prompt-level scope control 不能做到强约束,只能通过 trace 和测试观察遵循情况。
|
||||||
|
- 当前 mock 数据适合 demo,不代表生产接入已经完成。
|
||||||
|
- Hikari 连接池已经加了短生命周期和 keepalive,但真实生产还需要按数据库 wait_timeout 和连接数预算调优。
|
||||||
|
|
||||||
|
主动讲清这些限制,反而能体现工程判断:先把可追踪闭环打通,再逐步增强质量门和生产可靠性。
|
||||||
@@ -6,3 +6,32 @@
|
|||||||
| ISS-002 | Executor 无约束重复调用 lookup_knowledge | 中 | 已修复 | [ISS-002-executor-unconstrained-lookup.md](ISS-002-executor-unconstrained-lookup.md) |
|
| ISS-002 | Executor 无约束重复调用 lookup_knowledge | 中 | 已修复 | [ISS-002-executor-unconstrained-lookup.md](ISS-002-executor-unconstrained-lookup.md) |
|
||||||
| ISS-003 | MVP 设计与实现 Review 收敛 | 高 | 待规划 | [ISS-003-mvp-design-implementation-review.md](ISS-003-mvp-design-implementation-review.md) |
|
| ISS-003 | MVP 设计与实现 Review 收敛 | 高 | 待规划 | [ISS-003-mvp-design-implementation-review.md](ISS-003-mvp-design-implementation-review.md) |
|
||||||
| ISS-004 | Executor 域级检索水位控制(Phase 2) | 低 | 待规划 | [ISS-004-executor-domain-hard-limit.md](ISS-004-executor-domain-hard-limit.md) |
|
| ISS-004 | Executor 域级检索水位控制(Phase 2) | 低 | 待规划 | [ISS-004-executor-domain-hard-limit.md](ISS-004-executor-domain-hard-limit.md) |
|
||||||
|
|
||||||
|
## RAG 重构计划
|
||||||
|
|
||||||
|
| 名称 | 标题 | 严重程度 | 状态 | 文件 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| rag-refactor-plan | RAG 检索重构计划 | 高 | 待规划 | [rag-refactor-plan.md](rag-refactor-plan.md) |
|
||||||
|
|
||||||
|
## RAG 检索问题
|
||||||
|
|
||||||
|
| 名称 | 标题 | 严重程度 | 状态 | 文件 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| chunk-context-reconstruction | RAG 切片上下文重建缺失 | 高 | 已合并到重构计划 | [rag-chunk-context-reconstruction.md](rag-chunk-context-reconstruction.md) |
|
||||||
|
| breadcrumb-embedding-gap | RAG breadcrumb 未参与向量语义 | 高 | 已合并到重构计划 | [rag-breadcrumb-embedding-gap.md](rag-breadcrumb-embedding-gap.md) |
|
||||||
|
| l0-l1-fusion-ranking | RAG L0 和 L1 未真正融合排序 | 中 | 已合并到重构计划 | [rag-l0-l1-fusion-ranking.md](rag-l0-l1-fusion-ranking.md) |
|
||||||
|
| l0-keyword-matching-quality | RAG L0 关键词匹配质量不足 | 中 | 已合并到重构计划 | [rag-l0-keyword-matching-quality.md](rag-l0-keyword-matching-quality.md) |
|
||||||
|
| l1-score-calibration | RAG L1 分数阈值未校准 | 中 | 已合并到重构计划 | [rag-l1-score-calibration.md](rag-l1-score-calibration.md) |
|
||||||
|
| context-packing-and-reranking | RAG 缺少上下文打包和 Rerank | 中 | 已合并到重构计划 | [rag-context-packing-and-reranking.md](rag-context-packing-and-reranking.md) |
|
||||||
|
| upload-chunk-parameter-drift | RAG 上传切片参数未真正生效 | 低 | 已合并到重构计划 | [rag-upload-chunk-parameter-drift.md](rag-upload-chunk-parameter-drift.md) |
|
||||||
|
| query-rewrite-gap | RAG 查询改写能力薄弱 | 中 | 已合并到重构计划 | [rag-query-rewrite-gap.md](rag-query-rewrite-gap.md) |
|
||||||
|
|
||||||
|
## RAG 框架化改造
|
||||||
|
|
||||||
|
| 名称 | 标题 | 严重程度 | 状态 | 文件 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| spring-ai-vectorstore-migration | RAG 迁移到 Spring AI VectorStore 检索抽象 | 高 | 已合并到重构计划 | [rag-spring-ai-vectorstore-migration.md](rag-spring-ai-vectorstore-migration.md) |
|
||||||
|
| spring-ai-query-transformer | RAG 接入 Spring AI Query Transformer | 中 | 已合并到重构计划 | [rag-spring-ai-query-transformer.md](rag-spring-ai-query-transformer.md) |
|
||||||
|
| spring-ai-document-postprocessor | RAG 使用 DocumentPostProcessor 做后处理 | 中 | 已合并到重构计划 | [rag-spring-ai-document-postprocessor.md](rag-spring-ai-document-postprocessor.md) |
|
||||||
|
| l0-domain-entity-hint | RAG 将 L0 降级为领域和实体 Hint | 中 | 已合并到重构计划 | [rag-l0-domain-entity-hint.md](rag-l0-domain-entity-hint.md) |
|
||||||
|
| spring-ai-advisor-boundary | RAG 明确 Spring AI Advisor 与 Agent Tool 的边界 | 中 | 已合并到重构计划 | [rag-spring-ai-advisor-boundary.md](rag-spring-ai-advisor-boundary.md) |
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# RAG breadcrumb 未参与向量语义
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:高
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:向量化输入、检索相关性、知识库 metadata 使用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
当前 chunk metadata 中保存了 `title` 和 `breadcrumb`,但向量化时主要使用 `chunk.getContent()`。这意味着标题层级、所属模块、章节路径没有进入 embedding 语义空间。
|
||||||
|
|
||||||
|
当用户问题依赖章节语境时,例如“诊断流程里的验证步骤是什么”,如果 chunk 正文里没有重复出现完整标题语义,向量召回可能无法稳定命中正确片段。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- `DocumentChunkService` 会生成 `breadcrumb`。
|
||||||
|
- `VectorIndexService` 会把 `breadcrumb` 写入 metadata。
|
||||||
|
- `VectorEmbeddingService` 接收的 embedding 内容来自 chunk 正文。
|
||||||
|
- `VectorSearchService` 只基于 query embedding 和 chunk embedding 做向量搜索。
|
||||||
|
|
||||||
|
metadata 目前更像是展示和追踪字段,不是检索相关性的一部分。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- 标题语义丢失,尤其影响短段落、步骤列表、配置表格类 chunk。
|
||||||
|
- 同名概念出现在不同章节时,缺少章节路径帮助 disambiguation。
|
||||||
|
- 用户问的是“某个模块下的问题”,检索可能只看正文关键词,忽略模块归属。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
构建面向 embedding 的增强文本:
|
||||||
|
|
||||||
|
```text
|
||||||
|
标题: {title}
|
||||||
|
路径: {breadcrumb}
|
||||||
|
正文:
|
||||||
|
{content}
|
||||||
|
```
|
||||||
|
|
||||||
|
落库时仍保留原始 `content`,避免展示内容被污染。可以新增 `embeddingText` 构造逻辑,只用于向量化。
|
||||||
|
|
||||||
|
后续还可以在 rerank 阶段把 `breadcrumb` 作为加权信号,例如同域、同章节、同文档优先。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorEmbeddingService.java`
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# RAG 切片上下文重建缺失
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:高
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:知识库上传、切片、向量召回、Agent 上下文组装
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
同一个 Markdown 章节在内容较长时会被拆成多个 chunk。当前检索命中其中一个 chunk 后,返回给 Agent 的主要是单个 chunk 内容,不会自动把同章节的前后片段、章节标题链路、相邻 chunk 一起恢复出来。
|
||||||
|
|
||||||
|
这会导致两个问题:
|
||||||
|
|
||||||
|
1. 命中片段只包含局部语义,缺少前置定义、约束条件或后续步骤。
|
||||||
|
2. 同章节被分段后,检索结果之间缺少可追溯的关联,Agent 不一定知道它们属于同一章节。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- `DocumentChunkService` 会按 Markdown 标题建立 `title` 和 `breadcrumb`,再按段落累积切片。
|
||||||
|
- 超过阈值时仍会切断同一章节,只是尽量避免打断代码块和列表。
|
||||||
|
- `VectorIndexService` 会把 `chunkIndex`、`totalChunks`、`title`、`breadcrumb` 放入 metadata。
|
||||||
|
- `VectorSearchService` 查询 Milvus 后直接返回命中的 chunk,没有做相邻 chunk 扩展或 section 级聚合。
|
||||||
|
- `LookupKnowledgeTool` 消费 L1 结果时,也没有根据 `docId + chunkIndex + breadcrumb` 回补上下文。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- RAG 回答容易漏掉同章节中的约束条件。
|
||||||
|
- 长流程类文档会被拆散,Agent 看到的是“片段证据”,不是“完整流程”。
|
||||||
|
- 面试解释中需要承认:当前系统有 metadata 基础,但还没有把它用于上下文重建。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
优先做命中后的上下文扩展:
|
||||||
|
|
||||||
|
1. L1 命中 chunk 后,按 `docId + chunkIndex` 拉取前后 N 个相邻 chunk。
|
||||||
|
2. 如果 metadata 中 `breadcrumb` 相同,允许扩展到同章节的多个 chunk。
|
||||||
|
3. 上下文打包时标记 `命中片段`、`前文`、`后文`,避免 Agent 把扩展内容误认为全部都是高置信命中。
|
||||||
|
4. 增加 token budget 控制,超过预算时优先保留命中 chunk 和标题链路。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# RAG 缺少上下文打包和 Rerank
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:检索后处理、证据排序、Agent 输入质量
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
当前 RAG 检索主要依赖 L0/L1 的原始召回顺序,没有独立的 reranker、cross-encoder 或 LLM rerank 阶段。召回结果进入 Agent 前,也缺少统一的上下文打包策略。
|
||||||
|
|
||||||
|
这意味着“检索到”不等于“以最适合推理的形式喂给 Agent”。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- L0 和 L1 结果由 `LookupKnowledgeTool` 拼装后返回。
|
||||||
|
- 没有候选级 rerank。
|
||||||
|
- 没有明确的 token budget 分配策略,例如每个文档最多占多少、命中片段和扩展片段如何排序。
|
||||||
|
- 没有把 `title`、`breadcrumb`、score、source 统一包装成证据块。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- 相关结果可能被排在不理想的位置。
|
||||||
|
- 多个候选内容相近时,Agent 可能读到重复信息。
|
||||||
|
- 证据结构不清晰,后续 verifier 或 trace 解释成本较高。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
1. 引入 `RetrievedEvidence` 这样的内部结构,统一承载 source、title、breadcrumb、score、hitReason、content。
|
||||||
|
2. 做简单 rerank:关键词命中、向量分、breadcrumb 匹配、文档去重、相邻片段扩展一起排序。
|
||||||
|
3. 上下文打包时按证据块输出,明确来源和置信度。
|
||||||
|
4. 面试版可以先实现规则 rerank,后续再替换为 cross-encoder 或 LLM rerank。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
# RAG 将 L0 降级为领域和实体 Hint
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-05
|
||||||
|
**范围**:L0 检索、metadata filter、业务可解释性
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
当前 L0 是基于 frontmatter / keyword 的轻量检索。它具备可解释性,但不适合作为最终相关性判断。
|
||||||
|
|
||||||
|
在引入 Spring AI VectorStore / Retriever 后,L0 更适合从“召回主链路”调整为“检索前处理和解释信号”。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题
|
||||||
|
|
||||||
|
当前 L0 如果唯一命中,容易被过度信任:
|
||||||
|
|
||||||
|
```text
|
||||||
|
L0 unique hit -> 直接返回 / 优先采信
|
||||||
|
```
|
||||||
|
|
||||||
|
这会带来误召回风险,尤其是关键词过泛、frontmatter 质量不稳定时。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 改造方向
|
||||||
|
|
||||||
|
L0 保留,但职责调整为:
|
||||||
|
|
||||||
|
1. **Domain detector**
|
||||||
|
- 识别 query 所属 category/domain。
|
||||||
|
- 用于 Spring AI retriever metadata filter。
|
||||||
|
|
||||||
|
2. **Entity extractor**
|
||||||
|
- 识别组件名、服务名、指标名、错误码、接口名。
|
||||||
|
- 用于 query augmentation。
|
||||||
|
|
||||||
|
3. **Explainability signal**
|
||||||
|
- 记录 matched keywords。
|
||||||
|
- 解释为什么进入某个知识域。
|
||||||
|
|
||||||
|
目标链路:
|
||||||
|
|
||||||
|
```text
|
||||||
|
query / payload
|
||||||
|
-> L0 domain/entity hint
|
||||||
|
-> metadata filter + query augmentation
|
||||||
|
-> vector retriever
|
||||||
|
-> post processor
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
|
||||||
|
- L0 不再默认作为最终检索结果直接返回。
|
||||||
|
- L0 命中的 domain/category 能传给 retriever filter。
|
||||||
|
- L0 命中的实体能进入增强 query 或工具调用记录。
|
||||||
|
- `tool_invocation` 能展示 L0 matched keywords 和使用方式。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# RAG L0 关键词匹配质量不足
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:L0 索引、frontmatter、精确召回
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
L0 当前依赖文档 frontmatter 中的关键词,并使用较粗的字符串包含逻辑做匹配。关键词质量越依赖人工维护,召回稳定性越容易波动。
|
||||||
|
|
||||||
|
如果 frontmatter 填写不完整、同义词缺失、关键词过短或过泛,L0 就可能误召回或漏召回。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- `KnowledgeIndexService` 从 `ApiDocument` metadata/frontmatter 加载关键词。
|
||||||
|
- exact match 的判断类似:
|
||||||
|
|
||||||
|
```java
|
||||||
|
query.contains(keywordLower) || keywordLower.contains(query)
|
||||||
|
```
|
||||||
|
|
||||||
|
- 没有分词、同义词归一、字段权重、关键词质量校验。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- 短关键词容易误命中。
|
||||||
|
- 用户换一种说法时,L0 无法命中。
|
||||||
|
- 文档 frontmatter 质量变成检索质量的隐性前提。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
1. 为关键词增加最小长度、停用词、领域前缀等基础规则。
|
||||||
|
2. 区分 `exactKeywords`、`aliases`、`domainTags`,避免所有词混在一个匹配池。
|
||||||
|
3. 引入轻量中文分词或归一化策略,先不必上复杂搜索引擎。
|
||||||
|
4. 上传文档时校验 frontmatter 质量,缺失关键词时给出警告。
|
||||||
|
5. 在 issue 修复前,至少补一份知识库文档 frontmatter 编写规范。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentManagementService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/controller/DocumentController.java`
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# RAG L0 和 L1 未真正融合排序
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:知识检索工具、召回排序、Agent 证据质量
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
当前 `lookup_knowledge` 的 L0 和 L1 更像是串行兜底关系,不是真正的多路召回融合:
|
||||||
|
|
||||||
|
- L0 命中唯一结果时,直接返回 L0。
|
||||||
|
- L0 不唯一或不足时,才进入 L1。
|
||||||
|
- L1 查询 `topK=3`,但最终主要把第一条结果作为补充证据。
|
||||||
|
|
||||||
|
这会导致关键词召回和语义召回没有充分互补。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- `LookupKnowledgeTool` 先调用 `KnowledgeIndexService.exactMatch` 做 L0。
|
||||||
|
- 再按条件调用 `VectorSearchService.search` 做 L1。
|
||||||
|
- L0 和 L1 结果没有统一进入候选池做 fusion ranking。
|
||||||
|
- L1 多结果没有充分利用,相关性接近的候选可能被丢弃。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- L0 命中但质量一般时,会压过更好的 L1 语义结果。
|
||||||
|
- L1 找到多个相近片段时,只有 top1 被 Agent 看到,降低召回覆盖率。
|
||||||
|
- 难以解释检索排序,因为当前更像规则分支,不是可调的排序模型。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
建立统一候选池:
|
||||||
|
|
||||||
|
1. L0 和 L1 都返回候选列表。
|
||||||
|
2. 按 `docId/chunkId` 去重。
|
||||||
|
3. 为候选计算综合分:`keywordScore`、`vectorScore`、`domainScore`、`freshness`、`breadcrumbMatch`。
|
||||||
|
4. 取 topN 进入上下文打包,而不是只取 L1 top1。
|
||||||
|
5. 在 `tool_invocation` 中记录每个候选的分数组成,方便调试。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# RAG L1 分数阈值未校准
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:向量搜索、相关性判断、工具调用记录
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
L1 语义检索使用 Milvus 向量距离后,会做相关性归一和阈值判断。但当前阈值更偏经验值,没有基于真实查询集和真实分数分布做校准。
|
||||||
|
|
||||||
|
由于当前使用 L2 距离,不同 embedding 模型、不同语料密度、不同 query 长度都会影响分数分布。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- `VectorSearchService` 使用 query embedding 搜索 Milvus。
|
||||||
|
- Milvus metric type 为 `L2`。
|
||||||
|
- `LookupKnowledgeTool` 会把 L2 score 转成 normalized relevance。
|
||||||
|
- 阈值没有配套评测集或分布统计。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- 阈值过松时,低相关片段会进入 Agent 上下文。
|
||||||
|
- 阈值过紧时,正确片段可能被过滤掉。
|
||||||
|
- 面试中如果被追问“为什么这个阈值合理”,当前只能回答是 MVP 经验值。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
1. 固化一组 RAG 回归查询集,覆盖告警、数据库、流程规范、AIOps 诊断等场景。
|
||||||
|
2. 记录每次 topK 的原始 L2 score、归一化分数、最终是否采纳。
|
||||||
|
3. 统计正例和负例分布,确定阈值区间。
|
||||||
|
4. 将阈值配置化,并在 README 或 issue 中记录选择依据。
|
||||||
|
5. 后续引入 reranker 后,L1 阈值可以从“最终判断”退化为“粗召回过滤”。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/resources/application.yml`
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# RAG 查询改写能力薄弱
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:检索工具、Agent 查询生成、召回稳定性
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
当前检索主要使用 Agent 传入 `lookup_knowledge` 的原始 query。工具层没有显式的 query rewrite、同义词扩展、领域词补全或多 query 检索。
|
||||||
|
|
||||||
|
当用户问题口语化、上下文依赖强,或缺少领域关键词时,L0 和 L1 的召回都可能不稳定。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- Agent 决定何时调用 `lookup_knowledge` 和传入什么 query。
|
||||||
|
- `LookupKnowledgeTool` 接收 query 后直接进入 L0/L1 检索。
|
||||||
|
- 工具层没有把用户问题改写成多个检索 query。
|
||||||
|
- 也没有把当前任务域、Planner step、告警 payload 等上下文显式拼入检索 query。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- Agent query 写得好时召回正常,query 写得差时检索链路缺少兜底。
|
||||||
|
- AIOps 场景里,告警名称、服务名、指标名、故障类型之间的别名关系没有被充分利用。
|
||||||
|
- 很难稳定复现同一类问题的检索质量。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
1. 在工具层增加轻量 query rewrite:原始问题、领域词增强问题、关键词查询并行召回。
|
||||||
|
2. 对 AIOps 场景,把 alertName、service、metric、symptom 显式构造成检索 query。
|
||||||
|
3. 记录 rewrite 前后的 query 到 `tool_invocation`,便于分析。
|
||||||
|
4. 后续可以引入 LLM query rewrite,但 MVP 先用规则模板更可控。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
# RAG 检索重构计划
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:高
|
||||||
|
**发现时间**:2026-07-05
|
||||||
|
**范围**:RAG、检索、知识库、Agent Tool、AIOps 诊断证据链
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
将当前自研 RAG MVP 重构为“成熟框架能力 + 业务可观测编排”的架构:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Agent
|
||||||
|
-> lookup_knowledge Tool
|
||||||
|
-> L0 domain/entity hint
|
||||||
|
-> query augmentation / transformer
|
||||||
|
-> Spring AI Retriever / VectorStore
|
||||||
|
-> metadata filter
|
||||||
|
-> document postprocess
|
||||||
|
-> neighbor / section expansion
|
||||||
|
-> evidence packing
|
||||||
|
-> tool_invocation record
|
||||||
|
```
|
||||||
|
|
||||||
|
核心原则:
|
||||||
|
|
||||||
|
1. 通用 RAG 基础设施尽量交给 Spring AI / Spring AI Alibaba。
|
||||||
|
2. Agent 工具入口、AIOps 业务语义、证据追踪继续保留在项目内。
|
||||||
|
3. 不把系统改成隐式 Chat RAG,仍然保留显式 `lookup_knowledge` 工具调用。
|
||||||
|
4. 分阶段迁移,避免一次性推倒当前可运行链路。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前问题汇总
|
||||||
|
|
||||||
|
当前 RAG 已经打通上传、切片、向量化、L0/L1 召回和工具调用记录,但主要问题集中在:
|
||||||
|
|
||||||
|
1. **检索基础设施偏自研**
|
||||||
|
- Milvus 写入和查询直接使用 SDK。
|
||||||
|
- topK、threshold、metadata filter、结果结构由业务代码维护。
|
||||||
|
- 后续接入 Spring AI RAG 能力会有重复适配成本。
|
||||||
|
|
||||||
|
2. **L0 职责过重**
|
||||||
|
- 当前 L0 可能被当成最终召回决策。
|
||||||
|
- 关键词质量不稳定时容易误召回。
|
||||||
|
- 更适合作为 domain/entity hint,而不是最终答案来源。
|
||||||
|
|
||||||
|
3. **query 构造不稳定**
|
||||||
|
- 主要依赖 Agent 传入原始 query。
|
||||||
|
- AIOps payload 中的 alertName、service、metric、symptom 没有稳定进入检索 query。
|
||||||
|
|
||||||
|
4. **上下文重建不足**
|
||||||
|
- 同章节被切成多个 chunk 后,命中片段不会自动扩展前后文。
|
||||||
|
- `breadcrumb` 存在 metadata 中,但没有充分参与 embedding、filter 或 context packing。
|
||||||
|
|
||||||
|
5. **缺少检索后处理**
|
||||||
|
- 缺少统一 evidence block。
|
||||||
|
- 缺少去重、token budget、hitReason、source 结构化输出。
|
||||||
|
|
||||||
|
6. **缺少量化评测**
|
||||||
|
- 目前主要靠接口回放、日志和 `tool_invocation` 人工判断。
|
||||||
|
- 还没有 golden query set、Recall@K、MRR、NDCG 等检索评测。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 保留设计
|
||||||
|
|
||||||
|
这些设计值得保留,并作为重构后的项目亮点:
|
||||||
|
|
||||||
|
### 1. `lookup_knowledge` 显式 Agent Tool
|
||||||
|
|
||||||
|
保留显式工具调用,不直接用隐式 Advisor 取代。
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
- 面试项目重点是 Agent 工程,不是普通 Chat RAG。
|
||||||
|
- 显式工具调用能展示 Agent 何时检索、检索了什么、证据如何支撑诊断。
|
||||||
|
- `tool_invocation`、evidence score、diagnosis session 都依赖这条链路。
|
||||||
|
|
||||||
|
### 2. L0
|
||||||
|
|
||||||
|
保留 L0,但降级为:
|
||||||
|
|
||||||
|
- domain detector
|
||||||
|
- entity extractor
|
||||||
|
- metadata filter generator
|
||||||
|
- explainability signal
|
||||||
|
|
||||||
|
不再默认执行:
|
||||||
|
|
||||||
|
```text
|
||||||
|
L0 unique hit -> 直接返回
|
||||||
|
```
|
||||||
|
|
||||||
|
目标职责:
|
||||||
|
|
||||||
|
```text
|
||||||
|
query / payload
|
||||||
|
-> L0 matched keywords/entities/domain
|
||||||
|
-> metadata filter + query augmentation
|
||||||
|
-> retriever
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. metadata
|
||||||
|
|
||||||
|
保留并加强 metadata:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docId
|
||||||
|
chunkIndex
|
||||||
|
totalChunks
|
||||||
|
title
|
||||||
|
breadcrumb
|
||||||
|
category
|
||||||
|
source
|
||||||
|
```
|
||||||
|
|
||||||
|
后续可扩展:
|
||||||
|
|
||||||
|
```text
|
||||||
|
sectionId
|
||||||
|
parentSection
|
||||||
|
documentType
|
||||||
|
domain
|
||||||
|
tags
|
||||||
|
version
|
||||||
|
```
|
||||||
|
|
||||||
|
metadata 是 filter、上下文扩展、证据追踪、可解释性的基础。
|
||||||
|
|
||||||
|
### 4. Markdown-aware chunking
|
||||||
|
|
||||||
|
保留当前 Markdown 结构化切片思路:
|
||||||
|
|
||||||
|
- 识别标题层级
|
||||||
|
- 生成 `title`
|
||||||
|
- 生成 `breadcrumb`
|
||||||
|
- 保留 `chunkIndex`
|
||||||
|
- 尽量不打断列表和代码块
|
||||||
|
|
||||||
|
可以替换或复用框架能力的是底层 token 长度控制和 overlap 策略,而不是完全抛弃结构化切片。
|
||||||
|
|
||||||
|
### 5. `tool_invocation` 证据追踪
|
||||||
|
|
||||||
|
保留并增强:
|
||||||
|
|
||||||
|
```text
|
||||||
|
sessionId
|
||||||
|
query
|
||||||
|
rewrittenQuery
|
||||||
|
matchedKeywords
|
||||||
|
domain/entities
|
||||||
|
retrievedDocs
|
||||||
|
scores
|
||||||
|
hitReasons
|
||||||
|
evidence
|
||||||
|
duration
|
||||||
|
relevanceLevel
|
||||||
|
```
|
||||||
|
|
||||||
|
这是后续检索评测、诊断质量评估、面试讲解的基础。
|
||||||
|
|
||||||
|
### 6. AIOps payload 到 query 的业务映射
|
||||||
|
|
||||||
|
保留 AIOps 场景逻辑:
|
||||||
|
|
||||||
|
- alertName
|
||||||
|
- service
|
||||||
|
- metric
|
||||||
|
- symptom
|
||||||
|
- category/domain
|
||||||
|
|
||||||
|
这些是业务语义,不能完全交给通用框架隐式处理。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 替换设计
|
||||||
|
|
||||||
|
这些能力适合逐步交给 Spring AI / Spring AI Alibaba:
|
||||||
|
|
||||||
|
| 当前能力 | 目标能力 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| Milvus SDK 直接写入/查询 | Spring AI `VectorStore` | 减少基础设施代码 |
|
||||||
|
| 自研 `VectorSearchService` 检索细节 | `VectorStoreDocumentRetriever` | 标准化 topK、threshold、filter |
|
||||||
|
| 手写 query 拼接 | Query Transformer / 模板化 query augmentation | 先规则化,后框架化 |
|
||||||
|
| 手写结果拼接 | DocumentPostProcessor / evidence postprocess | 做去重、压缩、证据块 |
|
||||||
|
| L0 最终召回判断 | L0 domain/entity hint | 降低误召回风险 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 分阶段计划
|
||||||
|
|
||||||
|
### Phase 0:重构前基线
|
||||||
|
|
||||||
|
目标:先固定当前行为,避免重构后不知道是否变好。
|
||||||
|
|
||||||
|
任务:
|
||||||
|
|
||||||
|
- 固化 10-20 条 golden queries。
|
||||||
|
- 覆盖 Chat 和 AIOps 场景。
|
||||||
|
- 每条 query 标注 expected doc、breadcrumb、关键 chunk 或 evidence。
|
||||||
|
- 用当前链路跑一遍,记录 baseline。
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 有可重复运行的检索回放清单。
|
||||||
|
- 能记录当前 Recall@K、first hit rank 或人工 hit level。
|
||||||
|
|
||||||
|
### Phase 1:L0 降级为 domain/entity hint
|
||||||
|
|
||||||
|
目标:保留 L0 价值,降低 L0 误决策风险。
|
||||||
|
|
||||||
|
任务:
|
||||||
|
|
||||||
|
- `KnowledgeIndexService` 输出 matched keywords、domain、entities。
|
||||||
|
- `LookupKnowledgeTool` 不再把 L0 unique hit 作为默认最终结果。
|
||||||
|
- 将 L0 结果用于 query augmentation 和 metadata filter。
|
||||||
|
- `tool_invocation` 记录 L0 hit reason。
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- L0 命中不会绕过向量检索直接返回。
|
||||||
|
- 检索记录能看到 domain/entities/matchedKeywords。
|
||||||
|
- AIOps payload 能生成稳定领域 hint。
|
||||||
|
|
||||||
|
### Phase 2:Evidence Postprocess 和上下文打包
|
||||||
|
|
||||||
|
目标:先提升 Agent 实际拿到的证据质量。
|
||||||
|
|
||||||
|
任务:
|
||||||
|
|
||||||
|
- 定义 evidence block:
|
||||||
|
|
||||||
|
```text
|
||||||
|
source
|
||||||
|
docId
|
||||||
|
chunkIndex
|
||||||
|
title
|
||||||
|
breadcrumb
|
||||||
|
score
|
||||||
|
hitReason
|
||||||
|
content
|
||||||
|
expandedFrom
|
||||||
|
```
|
||||||
|
|
||||||
|
- 对检索结果做去重。
|
||||||
|
- 支持命中 chunk 的相邻 chunk / 同章节扩展。
|
||||||
|
- 加 token 或字符预算控制。
|
||||||
|
- 返回给 Agent 的内容按 evidence block 组织。
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 同一 docId/chunkIndex 不重复进入上下文。
|
||||||
|
- 命中 chunk 可以补充前后文。
|
||||||
|
- `tool_invocation` 记录 postprocess 前后候选数量和最终 evidence 数量。
|
||||||
|
|
||||||
|
### Phase 3:Spring AI VectorStore 旁路验证
|
||||||
|
|
||||||
|
目标:验证框架能力,不直接替换主链路。
|
||||||
|
|
||||||
|
任务:
|
||||||
|
|
||||||
|
- 引入 Spring AI Milvus VectorStore。
|
||||||
|
- 建立旁路 `SpringAiVectorSearchService` 或适配层。
|
||||||
|
- 同一批 golden queries 同时跑旧链路和新链路。
|
||||||
|
- 对比 topK、metadata、score、filter 行为。
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 旁路检索可跑通。
|
||||||
|
- metadata 不丢失。
|
||||||
|
- 查询结果与当前链路差异可解释。
|
||||||
|
- 不影响现有 Chat / AIOps 主链路。
|
||||||
|
|
||||||
|
### Phase 4:替换底层 VectorSearchService
|
||||||
|
|
||||||
|
目标:对外接口不变,内部检索切到 Spring AI VectorStore / Retriever。
|
||||||
|
|
||||||
|
任务:
|
||||||
|
|
||||||
|
- 保持 `LookupKnowledgeTool` 调用方式不变。
|
||||||
|
- `VectorSearchService` 内部迁移到 Spring AI 检索抽象。
|
||||||
|
- 支持 topK、similarity threshold、category metadata filter。
|
||||||
|
- 保留旧实现一段时间作为 fallback。
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- Chat / AIOps 检索链路行为兼容。
|
||||||
|
- golden queries 不低于 baseline。
|
||||||
|
- 检索结果仍能完整记录到 `tool_invocation`。
|
||||||
|
|
||||||
|
### Phase 5:Query Transformer 和框架化 PostProcessor
|
||||||
|
|
||||||
|
目标:在稳定的 VectorStore 基础上接入更成熟 RAG 能力。
|
||||||
|
|
||||||
|
任务:
|
||||||
|
|
||||||
|
- AIOps 场景优先使用模板化 query augmentation。
|
||||||
|
- 需要时接入 Spring AI Query Transformer / MultiQuery。
|
||||||
|
- 将现有 evidence postprocess 抽象成 DocumentPostProcessor 风格。
|
||||||
|
- 可选接入 rerank,但不作为第一优先级。
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 原始 query 和 rewritten query 都可追踪。
|
||||||
|
- query rewrite 失败可以 fallback。
|
||||||
|
- postprocess 行为可配置、可记录、可回放。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 暂不做
|
||||||
|
|
||||||
|
以下能力暂不进入近期重构:
|
||||||
|
|
||||||
|
1. 不做完整自研 RRF 框架。
|
||||||
|
2. 不直接把 `lookup_knowledge` 替换成隐式 Advisor。
|
||||||
|
3. 不一口气迁移所有 RAG ETL。
|
||||||
|
4. 不先引入 Elasticsearch / OpenSearch,除非评测证明 BM25 必须。
|
||||||
|
5. 不先上 cross-encoder / LLM rerank,先做规则型 evidence postprocess。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 风险
|
||||||
|
|
||||||
|
### 1. Milvus schema 兼容风险
|
||||||
|
|
||||||
|
当前 collection 是项目自建,Spring AI VectorStore 可能有自己的 schema 假设。需要旁路验证。
|
||||||
|
|
||||||
|
### 2. 检索行为变化风险
|
||||||
|
|
||||||
|
框架检索分数和当前 L2 score 可能不完全一致,需要 golden queries 对比。
|
||||||
|
|
||||||
|
### 3. 可观测性丢失风险
|
||||||
|
|
||||||
|
如果迁移到隐式 Advisor,可能丢失工具调用证据链。因此 Spring AI RAG 能力应优先封装在 `lookup_knowledge` 内部。
|
||||||
|
|
||||||
|
### 4. 重构范围膨胀风险
|
||||||
|
|
||||||
|
RAG、Agent、AIOps、数据库记录互相关联,必须分阶段推进,每阶段都保持可运行。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 合并来源
|
||||||
|
|
||||||
|
本计划合并以下问题和改造方向:
|
||||||
|
|
||||||
|
- [rag-chunk-context-reconstruction.md](rag-chunk-context-reconstruction.md)
|
||||||
|
- [rag-breadcrumb-embedding-gap.md](rag-breadcrumb-embedding-gap.md)
|
||||||
|
- [rag-l0-l1-fusion-ranking.md](rag-l0-l1-fusion-ranking.md)
|
||||||
|
- [rag-l0-keyword-matching-quality.md](rag-l0-keyword-matching-quality.md)
|
||||||
|
- [rag-l1-score-calibration.md](rag-l1-score-calibration.md)
|
||||||
|
- [rag-context-packing-and-reranking.md](rag-context-packing-and-reranking.md)
|
||||||
|
- [rag-upload-chunk-parameter-drift.md](rag-upload-chunk-parameter-drift.md)
|
||||||
|
- [rag-query-rewrite-gap.md](rag-query-rewrite-gap.md)
|
||||||
|
- [rag-spring-ai-vectorstore-migration.md](rag-spring-ai-vectorstore-migration.md)
|
||||||
|
- [rag-spring-ai-query-transformer.md](rag-spring-ai-query-transformer.md)
|
||||||
|
- [rag-spring-ai-document-postprocessor.md](rag-spring-ai-document-postprocessor.md)
|
||||||
|
- [rag-l0-domain-entity-hint.md](rag-l0-domain-entity-hint.md)
|
||||||
|
- [rag-spring-ai-advisor-boundary.md](rag-spring-ai-advisor-boundary.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentManagementService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/AiOpsService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java`
|
||||||
|
- `src/main/resources/application.yml`
|
||||||
|
- `pom.xml`
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# RAG 明确 Spring AI Advisor 与 Agent Tool 的边界
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-05
|
||||||
|
**范围**:Agent 编排、RAG Advisor、工具调用可观测性
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
Spring AI 提供 `QuestionAnswerAdvisor`、`RetrievalAugmentationAdvisor` 等 RAG Advisor 能力,可以把检索增强直接挂到模型调用流程中。
|
||||||
|
|
||||||
|
但当前项目是 Agent 工程项目,知识检索不是普通聊天增强,而是 Agent 在诊断流程中显式调用的工具。系统还依赖 `tool_invocation` 记录检索事实,用于 evidence score 和诊断追踪。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题
|
||||||
|
|
||||||
|
如果直接把 RAG 全部迁到 Advisor,可能会损失当前项目已有的显式工具链路:
|
||||||
|
|
||||||
|
1. Agent 是否调用知识库不够透明。
|
||||||
|
2. `tool_invocation` 记录可能变弱。
|
||||||
|
3. AIOps 诊断步骤和知识证据之间的对应关系不清晰。
|
||||||
|
4. 面试项目中“Agent 如何使用工具”的展示价值下降。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 改造方向
|
||||||
|
|
||||||
|
不要把 `lookup_knowledge` 完全替换成隐式 Advisor,而是分层使用:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Agent Tool 层:
|
||||||
|
lookup_knowledge
|
||||||
|
sessionId
|
||||||
|
traceId
|
||||||
|
tool_invocation
|
||||||
|
evidence score
|
||||||
|
|
||||||
|
Spring AI RAG 层:
|
||||||
|
query transformer
|
||||||
|
retriever
|
||||||
|
vector store
|
||||||
|
document post processor
|
||||||
|
```
|
||||||
|
|
||||||
|
也就是说,Advisor / Retriever 可以作为工具内部实现,而不是取代工具本身。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
|
||||||
|
- Agent 仍然通过显式 `lookup_knowledge` 使用知识库。
|
||||||
|
- Spring AI RAG 能力被封装在工具内部或服务内部。
|
||||||
|
- 每次检索仍能落 `tool_invocation`。
|
||||||
|
- Chat / AIOps 两条链路都能追踪检索输入、输出和证据来源。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/ChatService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/AiOpsService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java`
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# RAG 使用 DocumentPostProcessor 做后处理
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-05
|
||||||
|
**范围**:检索后处理、去重、上下文打包、轻量 rerank
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
当前检索结果返回给 Agent 前,主要依赖 `LookupKnowledgeTool` 自己拼接内容。系统还缺少统一的后处理阶段。
|
||||||
|
|
||||||
|
Spring AI RAG 流程中可以使用 DocumentPostProcessor 类能力,在文档进入模型上下文前做过滤、去重、压缩或 rerank。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题
|
||||||
|
|
||||||
|
当前检索后处理不足:
|
||||||
|
|
||||||
|
1. L1 topK 候选没有被充分利用。
|
||||||
|
2. 同文档或同章节结果可能重复。
|
||||||
|
3. 命中 chunk 后没有统一处理前后文扩展。
|
||||||
|
4. 证据块缺少统一格式,后续 verifier / evaluator 不容易复用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 改造方向
|
||||||
|
|
||||||
|
建立一个轻量后处理链:
|
||||||
|
|
||||||
|
```text
|
||||||
|
retrieved documents
|
||||||
|
-> deduplicate
|
||||||
|
-> optional neighbor / section expansion
|
||||||
|
-> score / reason annotation
|
||||||
|
-> token budget packing
|
||||||
|
-> evidence blocks
|
||||||
|
```
|
||||||
|
|
||||||
|
优先做规则型后处理,不急于引入 cross-encoder 或 LLM rerank。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
|
||||||
|
- 同一个 docId/chunkIndex 不重复进入 Agent 上下文。
|
||||||
|
- 最终返回内容包含 source、title、breadcrumb、score、hitReason。
|
||||||
|
- 可以限制单次工具调用返回的最大 token 或最大字符数。
|
||||||
|
- 后处理前后的候选数量、去重数量、最终 evidence 数量记录到 `tool_invocation`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java`
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# RAG 接入 Spring AI Query Transformer
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:中
|
||||||
|
**发现时间**:2026-07-05
|
||||||
|
**范围**:查询改写、多查询扩展、AIOps 检索稳定性
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
当前 `lookup_knowledge` 主要使用 Agent 传入的原始 query 进行 L0/L1 检索。query 的质量高度依赖 Agent 当次生成结果。
|
||||||
|
|
||||||
|
Spring AI 提供 Query Transformer / Query Expander 类能力,可以把用户问题或 Agent 子任务改写成更适合检索的查询。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题
|
||||||
|
|
||||||
|
当前检索 query 存在几个风险:
|
||||||
|
|
||||||
|
1. 用户问题口语化时,缺少领域关键词。
|
||||||
|
2. AIOps payload 中的 alertName、service、metric 没有稳定拼入检索 query。
|
||||||
|
3. 同义表达没有扩展,例如“连接耗尽”和“连接池打满”。
|
||||||
|
4. 工具层无法复用框架提供的 rewrite / expansion 能力。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 改造方向
|
||||||
|
|
||||||
|
在 `lookup_knowledge` 前增加查询改写层:
|
||||||
|
|
||||||
|
```text
|
||||||
|
raw query / alert payload
|
||||||
|
-> query transformer
|
||||||
|
-> rewritten query / expanded queries
|
||||||
|
-> retriever
|
||||||
|
```
|
||||||
|
|
||||||
|
优先支持两类场景:
|
||||||
|
|
||||||
|
1. **AIOps 模板化改写**
|
||||||
|
- alertName
|
||||||
|
- service
|
||||||
|
- metric
|
||||||
|
- symptom
|
||||||
|
- domain/category
|
||||||
|
|
||||||
|
2. **Spring AI Query Transformer**
|
||||||
|
- rewrite 原始 query
|
||||||
|
- multi-query expansion
|
||||||
|
- 必要时做 query compression
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
|
||||||
|
- `tool_invocation` 中记录原始 query 和改写后的 query。
|
||||||
|
- AIOps payload 存在时,检索 query 能稳定带上告警和服务上下文。
|
||||||
|
- 对同一个测试问题,改写前后 topK 命中结果可对比。
|
||||||
|
- 未配置 transformer 时,可以回退到原始 query。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/AiOpsService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/domain/entity/ToolInvocation.java`
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# RAG 迁移到 Spring AI VectorStore 检索抽象
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:高
|
||||||
|
**发现时间**:2026-07-05
|
||||||
|
**范围**:向量检索、Milvus 接入、RAG 框架化改造
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
当前系统的向量检索链路主要由项目手写实现:
|
||||||
|
|
||||||
|
- `VectorIndexService` 负责向量化和写入 Milvus。
|
||||||
|
- `VectorSearchService` 直接使用 Milvus SDK 查询。
|
||||||
|
- `LookupKnowledgeTool` 自己组织 L0/L1 检索结果。
|
||||||
|
|
||||||
|
这能满足 MVP 打通链路,但继续扩展 RAG 能力时,容易把项目变成自研搜索框架。
|
||||||
|
|
||||||
|
项目当前已引入 Spring AI / Spring AI Alibaba 依赖,可以考虑迁移到 Spring AI 的 `VectorStore`、`VectorStoreDocumentRetriever` 等标准抽象。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题
|
||||||
|
|
||||||
|
当前手写 Milvus 检索存在几个成本:
|
||||||
|
|
||||||
|
1. topK、similarity threshold、metadata filter 等逻辑分散在业务代码中。
|
||||||
|
2. 检索结果结构和 Spring AI RAG Advisor 生态不兼容。
|
||||||
|
3. 后续接入 query transformer、post processor、advisor 时需要重复适配。
|
||||||
|
4. Milvus SDK 直接调用让业务层承担了过多基础设施细节。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 改造方向
|
||||||
|
|
||||||
|
优先引入 Spring AI 的 Milvus VectorStore 能力:
|
||||||
|
|
||||||
|
```text
|
||||||
|
当前:
|
||||||
|
VectorSearchService -> Milvus SDK
|
||||||
|
|
||||||
|
目标:
|
||||||
|
LookupKnowledgeTool / RAG Service
|
||||||
|
-> VectorStoreDocumentRetriever
|
||||||
|
-> Spring AI VectorStore
|
||||||
|
-> Milvus
|
||||||
|
```
|
||||||
|
|
||||||
|
业务层保留:
|
||||||
|
|
||||||
|
- `lookup_knowledge` 工具入口
|
||||||
|
- `tool_invocation` 记录
|
||||||
|
- sessionId / category / domain 等业务上下文
|
||||||
|
|
||||||
|
底层检索交给框架:
|
||||||
|
|
||||||
|
- topK
|
||||||
|
- similarity threshold
|
||||||
|
- metadata filter
|
||||||
|
- vector search options
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
|
||||||
|
- `VectorSearchService` 不再直接散落 Milvus 查询细节,至少封装到 Spring AI `VectorStore` 适配层。
|
||||||
|
- 支持按 `category` 或其他 metadata filter 检索。
|
||||||
|
- 检索结果仍能记录到 `tool_invocation`。
|
||||||
|
- 现有 AIOps / Chat 检索链路行为保持兼容。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `pom.xml`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/VectorIndexService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
|
||||||
|
- `src/main/resources/application.yml`
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# RAG 上传切片参数未真正生效
|
||||||
|
|
||||||
|
**状态**:待规划
|
||||||
|
**严重程度**:低
|
||||||
|
**发现时间**:2026-07-04
|
||||||
|
**范围**:文档上传接口、切片配置、API 行为一致性
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现象
|
||||||
|
|
||||||
|
上传接口暴露了 `chunkSize` 和 `chunkOverlap` 参数,但实际切片主要使用全局 `DocumentChunkConfig`。这会造成 API 表面能力和真实行为不一致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
- `DocumentController` 的上传接口接收 `chunkSize` 和 `chunkOverlap`。
|
||||||
|
- 这些字段会进入 `DocumentUploadRequest`。
|
||||||
|
- `DocumentChunkService` 的切片阈值主要来自 `DocumentChunkConfig`。
|
||||||
|
- 单次上传请求中的参数没有真正覆盖切片配置。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 影响
|
||||||
|
|
||||||
|
- 调用方以为可以控制切片大小,但实际无法影响结果。
|
||||||
|
- 测试时容易误判“参数调优无效”的原因。
|
||||||
|
- 面试中如果展示 API,会被追问参数是否真实生效。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复
|
||||||
|
|
||||||
|
两个方向二选一:
|
||||||
|
|
||||||
|
1. 如果 MVP 不需要请求级切片参数,就从接口中移除或标记为暂不支持。
|
||||||
|
2. 如果需要支持,就让 `DocumentChunkService` 接收 per-request chunk options,并记录到文档 metadata 中。
|
||||||
|
|
||||||
|
建议面试项目中优先选择第二种,因为它更能体现工程闭环:API、配置、落库、追踪一致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- `src/main/java/com/superbiz/agent/controller/DocumentController.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentManagementService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java`
|
||||||
|
- `src/main/java/com/superbiz/agent/config/DocumentChunkConfig.java`
|
||||||
Reference in New Issue
Block a user