Merge branch 'emdash/afraid-geese-carry-h5718' into refactor/mvp1.0
# Conflicts: # devflow/index.md
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# AI Ops Prompt 配置化 & LookupKnowledgeTool 集成
|
||||
|
||||
**日期**: 2026-06-24
|
||||
**类型**: 功能增强 + 架构优化
|
||||
**影响范围**: AI Ops 服务
|
||||
|
||||
---
|
||||
|
||||
## 一、变更背景
|
||||
|
||||
### 1.1 问题
|
||||
|
||||
- **硬编码 Prompt**:Planner、Executor、Supervisor 的系统提示词硬编码在 `AiOpsService.java` 中,难以维护和版本控制
|
||||
- **缺少知识库精确检索**:现有 `InternalDocsTools` 只支持 L1 语义检索(200-500ms),对于错误码、配置项等精确关键词查询效率较低
|
||||
|
||||
### 1.2 解决方案
|
||||
|
||||
1. **Prompt 配置化**:将所有 Agent 的 Prompt 抽取到 `prompts/ai-ops-prompts.yml` 配置文件
|
||||
2. **集成 L0+L1 混合检索**:引入 `LookupKnowledgeTool`,支持精确关键词匹配(< 10ms)+ 语义检索补充
|
||||
|
||||
---
|
||||
|
||||
## 二、架构变更
|
||||
|
||||
### 2.1 Prompt 配置化架构
|
||||
|
||||
```
|
||||
AiOpsService
|
||||
↓ 注入
|
||||
AiOpsPromptProperties (配置类)
|
||||
↓ @PostConstruct 加载
|
||||
ClassPathResource 读取 Markdown 文件
|
||||
↓ 读取
|
||||
prompts/
|
||||
├── planner-prompt.md
|
||||
├── executor-prompt.md
|
||||
└── supervisor-prompt.md
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- 易于维护:Prompt 修改不需要重新编译
|
||||
- 格式友好:Markdown 格式支持代码块、表格,无 YAML 转义问题
|
||||
- 版本控制:配置文件独立管理
|
||||
- 易于扩展:后续可按环境区分(dev/prod)
|
||||
|
||||
### 2.2 工具层增强
|
||||
|
||||
```
|
||||
原有工具:
|
||||
- queryInternalDocs (纯 L1 语义检索,200-500ms)
|
||||
|
||||
新增工具:
|
||||
- lookup_knowledge (L0 精确匹配 + L1 补充,< 10ms 高置信度)
|
||||
```
|
||||
|
||||
**使用策略**:
|
||||
- 精确关键词(错误码、配置项)→ `lookup_knowledge`,未找到时降级到 `queryInternalDocs`
|
||||
- 模糊概念、故障流程 → 直接使用 `queryInternalDocs`
|
||||
|
||||
---
|
||||
|
||||
## 三、核心改动
|
||||
|
||||
### 3.1 新增文件
|
||||
|
||||
#### `AiOpsPromptProperties.java`
|
||||
```java
|
||||
@Configuration
|
||||
public class AiOpsPromptProperties {
|
||||
private String planner;
|
||||
private String executor;
|
||||
private String supervisor;
|
||||
|
||||
@PostConstruct
|
||||
public void loadPrompts() {
|
||||
planner = loadPromptFromFile("prompts/planner-prompt.md");
|
||||
executor = loadPromptFromFile("prompts/executor-prompt.md");
|
||||
supervisor = loadPromptFromFile("prompts/supervisor-prompt.md");
|
||||
}
|
||||
|
||||
private String loadPromptFromFile(String path) throws IOException {
|
||||
ClassPathResource resource = new ClassPathResource(path);
|
||||
return new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `prompts/*.md`
|
||||
三个独立的 Markdown 文件,包含 Agent 的完整系统提示词:
|
||||
- `planner-prompt.md` - Planner Agent 系统提示词
|
||||
- `executor-prompt.md` - Executor Agent 系统提示词(含工具选择指南)
|
||||
- `supervisor-prompt.md` - Supervisor Agent 系统提示词
|
||||
|
||||
### 3.2 修改文件
|
||||
|
||||
#### `AiOpsService.java`
|
||||
|
||||
**注入新组件**:
|
||||
```java
|
||||
@Autowired
|
||||
private LookupKnowledgeTool lookupKnowledgeTool;
|
||||
|
||||
@Autowired
|
||||
private AiOpsPromptProperties promptProperties;
|
||||
```
|
||||
|
||||
**使用配置化 Prompt**:
|
||||
```java
|
||||
// 原来
|
||||
.systemPrompt(buildPlannerPrompt())
|
||||
|
||||
// 改为
|
||||
.systemPrompt(promptProperties.getPlanner())
|
||||
```
|
||||
|
||||
**添加工具到工具数组**:
|
||||
```java
|
||||
return new Object[]{
|
||||
dateTimeTools,
|
||||
internalDocsTools,
|
||||
queryMetricsTools,
|
||||
lookupKnowledgeTool // 新增
|
||||
};
|
||||
```
|
||||
|
||||
**删除方法**:
|
||||
- `buildPlannerPrompt()`
|
||||
- `buildExecutorPrompt()`
|
||||
- `buildSupervisorSystemPrompt()`
|
||||
|
||||
---
|
||||
|
||||
## 四、Executor Prompt 变更详情
|
||||
|
||||
### 4.1 新增工具选择指南
|
||||
|
||||
```yaml
|
||||
- 根据查询内容选择合适的工具:
|
||||
* 精确关键词(错误码、配置项名称)→ 优先使用 lookup_knowledge,未找到时降级到 queryInternalDocs
|
||||
* 模糊概念、故障流程 → 直接使用 queryInternalDocs
|
||||
* 告警数据 → queryPrometheusAlerts
|
||||
* 日志数据 → queryLogs
|
||||
```
|
||||
|
||||
### 4.2 降级策略
|
||||
|
||||
关键改进:明确了 `lookup_knowledge` 未找到时的降级策略。
|
||||
|
||||
**流程**:
|
||||
```
|
||||
1. Planner: "查询 ERR_TIMEOUT 定义"
|
||||
2. Executor: 调用 lookup_knowledge("ERR_TIMEOUT")
|
||||
3a. 如果 found=true, confidence=high → 使用 primary.content
|
||||
3b. 如果 found=false → 自动降级到 queryInternalDocs("ERR_TIMEOUT 超时错误")
|
||||
4. 返回 feedback 给 Planner
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、兼容性说明
|
||||
|
||||
### 5.1 向后兼容
|
||||
|
||||
✅ **完全兼容**:
|
||||
- 现有工具调用逻辑不变
|
||||
- 3-Agent 协同模式不变
|
||||
- Planner/Executor/Supervisor 的职责边界不变
|
||||
|
||||
### 5.2 新增依赖
|
||||
|
||||
- `LookupKnowledgeTool` 依赖 `KnowledgeIndexService` 和 `VectorSearchService`
|
||||
- 需要 `knowledge_base/` 目录存在(已在 `application.yml` 中配置)
|
||||
|
||||
---
|
||||
|
||||
## 六、验证清单
|
||||
|
||||
### 6.1 编译验证
|
||||
|
||||
```bash
|
||||
mvn clean compile -DskipTests
|
||||
```
|
||||
|
||||
✅ **结果**: BUILD SUCCESS
|
||||
|
||||
### 6.2 运行时验证(待完成)
|
||||
|
||||
- [ ] 启动应用,验证 Prompt 配置加载成功
|
||||
- [ ] 触发 AI Ops 流程,验证 `lookup_knowledge` 工具可调用
|
||||
- [ ] 测试精确关键词查询(如 "ERR_TIMEOUT")
|
||||
- [ ] 测试降级策略(查询不存在的关键词)
|
||||
|
||||
---
|
||||
|
||||
## 七、后续工作
|
||||
|
||||
### 7.1 知识库内容准备
|
||||
|
||||
当前 `knowledge_base/` 目录需要补充文档:
|
||||
- 错误码定义(支付网关、订单系统等)
|
||||
- 配置最佳实践(Redis、HikariCP、Flyway 等)
|
||||
- 故障排查流程
|
||||
|
||||
**文档格式示例**:
|
||||
```markdown
|
||||
---
|
||||
title: 支付网关错误码定义
|
||||
keywords: [ERR_TIMEOUT, 超时, 支付网关]
|
||||
summary: 记录了支付网关所有核心错误码的含义及排查方向
|
||||
category: api
|
||||
---
|
||||
|
||||
# 支付网关错误码定义
|
||||
|
||||
## ERR_TIMEOUT
|
||||
...
|
||||
```
|
||||
|
||||
### 7.2 Prompt 优化
|
||||
|
||||
基于实际运行反馈,持续优化 `prompts/ai-ops-prompts.yml` 中的提示词。
|
||||
|
||||
### 7.3 可观测性增强
|
||||
|
||||
- 监控 `lookup_knowledge` 的调用频率和命中率
|
||||
- 记录降级场景(L0 未找到 → L1 补充)
|
||||
|
||||
---
|
||||
|
||||
## 八、参考文档
|
||||
|
||||
- [知识库检索架构说明](../mvp/architecture/knowledge-retrieval-architecture.md)
|
||||
- [AI Ops 核心设计 Essence 报告](../docs/learning/01-AI-Ops-核心设计-Essence报告.md)
|
||||
@@ -0,0 +1,100 @@
|
||||
# Prompt 配置化改进总结
|
||||
|
||||
**日期**: 2026-06-24
|
||||
**改进**: 从 YAML 配置改为 Markdown 文件
|
||||
|
||||
---
|
||||
|
||||
## 改进原因
|
||||
|
||||
YAML 格式存在以下问题:
|
||||
1. **多行字符串缩进敏感**:容易出现格式错误
|
||||
2. **转义字符复杂**:代码块、表格需要转义处理
|
||||
3. **可读性差**:长文本在 YAML 中难以阅读和维护
|
||||
|
||||
Markdown 格式优势:
|
||||
- ✅ 原生支持代码块、表格、列表
|
||||
- ✅ 无需转义,所见即所得
|
||||
- ✅ 版本控制 diff 更清晰
|
||||
- ✅ 编辑器语法高亮支持好
|
||||
|
||||
---
|
||||
|
||||
## 最终方案
|
||||
|
||||
### 文件结构
|
||||
```
|
||||
src/main/resources/prompts/
|
||||
├── planner-prompt.md # Planner Agent 系统提示词
|
||||
├── executor-prompt.md # Executor Agent 系统提示词
|
||||
└── supervisor-prompt.md # Supervisor Agent 系统提示词
|
||||
```
|
||||
|
||||
### 加载方式
|
||||
```java
|
||||
@Configuration
|
||||
public class AiOpsPromptProperties {
|
||||
|
||||
@PostConstruct
|
||||
public void loadPrompts() {
|
||||
planner = loadPromptFromFile("prompts/planner-prompt.md");
|
||||
executor = loadPromptFromFile("prompts/executor-prompt.md");
|
||||
supervisor = loadPromptFromFile("prompts/supervisor-prompt.md");
|
||||
}
|
||||
|
||||
private String loadPromptFromFile(String path) throws IOException {
|
||||
ClassPathResource resource = new ClassPathResource(path);
|
||||
return new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 使用方式
|
||||
```java
|
||||
@Autowired
|
||||
private AiOpsPromptProperties promptProperties;
|
||||
|
||||
// 直接使用
|
||||
.systemPrompt(promptProperties.getPlanner())
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 编译验证
|
||||
|
||||
```bash
|
||||
mvn clean compile -DskipTests
|
||||
```
|
||||
|
||||
✅ **结果**: BUILD SUCCESS
|
||||
|
||||
---
|
||||
|
||||
## 完整改动清单
|
||||
|
||||
| 文件 | 改动 |
|
||||
|------|------|
|
||||
| `AiOpsService.java` | 注入 `LookupKnowledgeTool` + `AiOpsPromptProperties` |
|
||||
| `AiOpsPromptProperties.java` | 从 Markdown 文件加载 Prompt(使用 `@PostConstruct`)|
|
||||
| `prompts/planner-prompt.md` | 新增:Planner 系统提示词 |
|
||||
| `prompts/executor-prompt.md` | 新增:Executor 系统提示词(含工具选择指南)|
|
||||
| `prompts/supervisor-prompt.md` | 新增:Supervisor 系统提示词 |
|
||||
| ~~`YamlPropertySourceFactory.java`~~ | 已删除(不再需要)|
|
||||
| ~~`prompts/ai-ops-prompts.yml`~~ | 已删除(改用 Markdown)|
|
||||
|
||||
---
|
||||
|
||||
## Executor Prompt 关键改进
|
||||
|
||||
新增工具选择指南:
|
||||
```markdown
|
||||
- 根据查询内容选择合适的工具:
|
||||
* 精确关键词(错误码、配置项名称)→ 优先使用 lookup_knowledge,未找到时降级到 queryInternalDocs
|
||||
* 模糊概念、故障流程 → 直接使用 queryInternalDocs
|
||||
* 告警数据 → queryPrometheusAlerts
|
||||
* 日志数据 → queryLogs
|
||||
```
|
||||
|
||||
降级策略:
|
||||
- `lookup_knowledge` 未找到 → 自动降级到 `queryInternalDocs`
|
||||
- 确保查询不会因为知识库缺少内容而失败
|
||||
@@ -0,0 +1,469 @@
|
||||
# 知识库初始化 API 使用文档
|
||||
|
||||
## 概述
|
||||
|
||||
提供了知识库批量初始化接口,用于将 `knowledge_base` 目录下的所有 Markdown 文档导入到数据库和向量索引(L0 + L1)。
|
||||
|
||||
**功能特点**:
|
||||
1. ✅ **批量扫描**:递归扫描 knowledge_base 目录下所有 .md 文件
|
||||
2. ✅ **自动去重**:基于文件路径检查,避免重复导入
|
||||
3. ✅ **数据入库**:保存文档元数据到 MySQL
|
||||
4. ✅ **L0 索引**:自动加入内存精确匹配索引
|
||||
5. ✅ **L1 索引**:文档分块并上传到 Milvus 向量数据库
|
||||
|
||||
---
|
||||
|
||||
## API 接口
|
||||
|
||||
### 1. 初始化知识库
|
||||
|
||||
**端点**:
|
||||
```
|
||||
POST /api/knowledge/init?force=false
|
||||
```
|
||||
|
||||
**参数**:
|
||||
- `force`(可选):是否强制重新导入,跳过去重检查
|
||||
- `false`(默认):跳过已存在的文档
|
||||
- `true`:强制重新导入所有文档
|
||||
|
||||
**请求示例**:
|
||||
```bash
|
||||
# 首次导入(去重模式)
|
||||
curl -X POST http://localhost:9900/api/knowledge/init
|
||||
|
||||
# 强制重新导入
|
||||
curl -X POST http://localhost:9900/api/knowledge/init?force=true
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "知识库初始化完成",
|
||||
"scanned": 6,
|
||||
"skipped": 0,
|
||||
"inserted": 6,
|
||||
"failed": 0,
|
||||
"details": {
|
||||
"api/payment-errors.md": "导入成功(L0+L1)",
|
||||
"domain/spring-ai-tool-best-practices.md": "导入成功(L0+L1)",
|
||||
"infrastructure/flyway-best-practices.md": "导入成功(L0+L1)",
|
||||
"infrastructure/mysql-connection-pool.md": "导入成功(L0+L1)",
|
||||
"infrastructure/redis-config.md": "导入成功(L0+L1)",
|
||||
"troubleshooting/fault-diagnosis-process.md": "导入成功(L0+L1)"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `scanned`:扫描到的文件总数
|
||||
- `skipped`:跳过的文件数量(已存在)
|
||||
- `inserted`:成功导入的文件数量
|
||||
- `failed`:失败的文件数量
|
||||
- `details`:每个文件的处理结果详情
|
||||
|
||||
---
|
||||
|
||||
### 2. 查询知识库统计
|
||||
|
||||
**端点**:
|
||||
```
|
||||
GET /api/knowledge/stats
|
||||
```
|
||||
|
||||
**请求示例**:
|
||||
```bash
|
||||
curl http://localhost:9900/api/knowledge/stats
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"totalDocuments": 6,
|
||||
"totalVectors": 48,
|
||||
"categories": {
|
||||
"api": 1,
|
||||
"domain": 1,
|
||||
"infrastructure": 3,
|
||||
"troubleshooting": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `totalDocuments`:数据库中的文档总数
|
||||
- `totalVectors`:Milvus 中的向量总数(chunk 数量)
|
||||
- `categories`:按分类统计的文档数量
|
||||
|
||||
---
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 场景 1:项目启动时初始化
|
||||
|
||||
```bash
|
||||
# 1. 启动应用
|
||||
mvn spring-boot:run
|
||||
|
||||
# 2. 等待应用启动完成(约 10 秒)
|
||||
|
||||
# 3. 调用初始化接口
|
||||
curl -X POST http://localhost:9900/api/knowledge/init
|
||||
|
||||
# 4. 查看结果
|
||||
# 日志输出:知识库初始化完成: 扫描=6, 跳过=0, 新增=6, 失败=0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景 2:添加新文档后重新初始化
|
||||
|
||||
```bash
|
||||
# 1. 添加新文档到 knowledge_base 目录
|
||||
echo "---
|
||||
title: 新文档
|
||||
keywords: [测试, test]
|
||||
summary: 这是一个测试文档
|
||||
category: test
|
||||
---
|
||||
|
||||
# 新文档内容
|
||||
" > knowledge_base/test/new-doc.md
|
||||
|
||||
# 2. 调用初始化接口(去重模式)
|
||||
curl -X POST http://localhost:9900/api/knowledge/init
|
||||
|
||||
# 3. 查看结果
|
||||
# 只会导入新文档,跳过已存在的 6 个文档
|
||||
# 响应: scanned=7, skipped=6, inserted=1, failed=0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景 3:强制重新导入所有文档
|
||||
|
||||
```bash
|
||||
# 适用场景:
|
||||
# - 数据库被清空,需要重新导入
|
||||
# - 文档内容有更新,需要刷新
|
||||
# - 索引损坏,需要重建
|
||||
|
||||
curl -X POST http://localhost:9900/api/knowledge/init?force=true
|
||||
|
||||
# 响应: scanned=6, skipped=0, inserted=6, failed=0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 去重机制
|
||||
|
||||
### 去重依据
|
||||
- **文件路径**:相对于 `knowledge_base` 目录的相对路径
|
||||
- 示例:`api/payment-errors.md`
|
||||
|
||||
### 去重逻辑
|
||||
```
|
||||
if (!force && existingFilePaths.contains(relativePath)) {
|
||||
跳过该文档
|
||||
} else {
|
||||
导入该文档
|
||||
}
|
||||
```
|
||||
|
||||
### 注意事项
|
||||
1. **文件移动会被视为新文档**:
|
||||
```bash
|
||||
# 移动前:api/payment-errors.md
|
||||
# 移动后:errors/payment-errors.md
|
||||
# 结果:会被当作两个不同的文档
|
||||
```
|
||||
|
||||
2. **文件重命名会被视为新文档**:
|
||||
```bash
|
||||
# 重命名前:payment-errors.md
|
||||
# 重命名后:payment-error-codes.md
|
||||
# 结果:会被当作两个不同的文档
|
||||
```
|
||||
|
||||
3. **内容更新不触发重新导入**(非 force 模式):
|
||||
```bash
|
||||
# 修改文件内容后调用 init(非 force)
|
||||
# 结果:跳过该文档,数据库中仍是旧内容
|
||||
# 解决:使用 force=true 强制重新导入
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 数据存储
|
||||
|
||||
### 完整的数据流
|
||||
|
||||
```
|
||||
knowledge_base/*.md
|
||||
↓ 1. 扫描
|
||||
KnowledgeBaseInitService
|
||||
↓ 2. 解析 frontmatter
|
||||
Frontmatter (title, keywords, summary)
|
||||
↓ 3. 保存到数据库
|
||||
MySQL (api_document)
|
||||
↓ 4. 提取正文 & 分块
|
||||
DocumentChunkService
|
||||
↓ 5. 生成向量
|
||||
VectorEmbeddingService
|
||||
↓ 6. 索引到 Milvus
|
||||
Milvus (L1 向量索引)
|
||||
↓ 7. 加入内存索引
|
||||
KnowledgeIndexService (L0)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 数据库表结构(api_document)
|
||||
|
||||
| 字段 | 类型 | 说明 | 示例 |
|
||||
|------|------|------|------|
|
||||
| `id` | BIGINT | 主键 | 1 |
|
||||
| `doc_id` | VARCHAR(64) | 文档唯一标识 | uuid |
|
||||
| `file_name` | VARCHAR(256) | 文件名 | payment-errors.md |
|
||||
| `file_path` | VARCHAR(512) | 相对路径 | api/payment-errors.md |
|
||||
| `api_name` | VARCHAR(128) | 文档标题 | 支付网关错误码定义 |
|
||||
| `status` | VARCHAR(16) | 状态 | INDEXED / FAILED |
|
||||
| `chunk_count` | INT | 分块数量 | 8 |
|
||||
| `error_message` | TEXT | 错误信息 | null |
|
||||
| `metadata` | TEXT | Frontmatter JSON | {"title":"...","keywords":[...]} |
|
||||
| `file_size` | BIGINT | 文件大小(字节) | 2048 |
|
||||
| `indexed_at` | DATETIME | 索引时间 | 2026-06-25 10:00:00 |
|
||||
|
||||
### metadata JSON 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "支付网关错误码定义",
|
||||
"summary": "记录了支付网关所有核心错误码的含义及排查方向",
|
||||
"category": "api",
|
||||
"keywords": ["ERR_TIMEOUT","超时","支付网关"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Milvus 向量索引
|
||||
|
||||
每个文档会被分块(chunk)并生成向量,存储到 Milvus 集合中:
|
||||
|
||||
**Collection**: `knowledge_base_collection`
|
||||
|
||||
**字段**:
|
||||
- `doc_id`:文档 ID
|
||||
- `chunk_id`:分块 ID
|
||||
- `chunk_text`:分块文本内容
|
||||
- `embedding`:768 维向量
|
||||
- `category`:文档分类
|
||||
- `file_path`:文件路径
|
||||
|
||||
**分块策略**:
|
||||
- Chunk Size:根据 `DocumentChunkConfig` 配置(默认 500 token)
|
||||
- Overlap:重叠区域(默认 50 token)
|
||||
|
||||
---
|
||||
|
||||
## L0 内存索引
|
||||
|
||||
导入过程会自动将文档加入 `KnowledgeIndexService` 的内存索引:
|
||||
|
||||
```java
|
||||
KnowledgeEntry entry = KnowledgeEntry.builder()
|
||||
.filePath(relativePath)
|
||||
.title(title)
|
||||
.keywords(keywords)
|
||||
.summary(summary)
|
||||
.category(category)
|
||||
.build();
|
||||
knowledgeIndexService.addToIndex(entry);
|
||||
```
|
||||
|
||||
**验证 L0 索引**:
|
||||
```bash
|
||||
# 应用启动后查看日志
|
||||
grep "知识库索引加载完成" logs/application.log
|
||||
|
||||
# 输出示例:
|
||||
# [INFO] 知识库索引加载完成,共 6 个文档
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 常见错误
|
||||
|
||||
#### 1. 目录不存在
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "初始化失败: 知识库目录不存在: knowledge_base"
|
||||
}
|
||||
```
|
||||
|
||||
**解决**:
|
||||
```bash
|
||||
mkdir -p knowledge_base/api
|
||||
mkdir -p knowledge_base/infrastructure
|
||||
mkdir -p knowledge_base/domain
|
||||
mkdir -p knowledge_base/troubleshooting
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 2. 文档格式无效
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"scanned": 6,
|
||||
"inserted": 5,
|
||||
"failed": 1,
|
||||
"details": {
|
||||
"test/invalid.md": "格式无效: frontmatter 解析失败"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- 缺少 frontmatter
|
||||
- YAML 格式错误
|
||||
- 缺少必填字段(title, keywords, summary)
|
||||
|
||||
**解决**:
|
||||
```markdown
|
||||
---
|
||||
title: 文档标题
|
||||
keywords: [关键词1, 关键词2]
|
||||
summary: 文档摘要
|
||||
category: api
|
||||
---
|
||||
|
||||
# 正文内容
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 问题 4: Milvus 连接失败
|
||||
|
||||
**症状**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"scanned": 6,
|
||||
"inserted": 0,
|
||||
"failed": 6,
|
||||
"details": {
|
||||
"api/payment-errors.md": "Milvus 索引失败: Connection refused"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- Milvus 服务未启动
|
||||
- 网络连接问题
|
||||
- 配置错误
|
||||
|
||||
**解决**:
|
||||
```bash
|
||||
# 检查 Milvus 是否运行
|
||||
docker ps | grep milvus
|
||||
|
||||
# 检查配置
|
||||
grep milvus application.yml
|
||||
|
||||
# 启动 Milvus
|
||||
docker-compose up -d milvus-standalone
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 问题 5: 文档分块失败
|
||||
|
||||
**症状**:
|
||||
```json
|
||||
{
|
||||
"details": {
|
||||
"test/large-doc.md": "Milvus 索引失败: Document too large"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- 文档内容过大
|
||||
- 分块配置不当
|
||||
|
||||
**解决**:
|
||||
- 检查 `DocumentChunkConfig` 配置
|
||||
- 调整 chunk size 和 overlap
|
||||
|
||||
---
|
||||
|
||||
#### 3. 文档缺少标题
|
||||
```json
|
||||
{
|
||||
"details": {
|
||||
"test/no-title.md": "缺少标题"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**解决**:在 frontmatter 中添加 `title` 字段。
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### ✅ 推荐做法
|
||||
|
||||
1. **首次启动后立即初始化**:
|
||||
```bash
|
||||
mvn spring-boot:run
|
||||
sleep 15 # 等待启动完成
|
||||
curl -X POST http://localhost:9900/api/knowledge/init
|
||||
```
|
||||
|
||||
2. **新增文档后增量导入**:
|
||||
```bash
|
||||
# 不使用 force,只导入新文档
|
||||
curl -X POST http://localhost:9900/api/knowledge/init
|
||||
```
|
||||
|
||||
3. **定期检查统计信息**:
|
||||
```bash
|
||||
curl http://localhost:9900/api/knowledge/stats
|
||||
```
|
||||
|
||||
4. **更新文档内容后强制刷新**:
|
||||
```bash
|
||||
curl -X POST http://localhost:9900/api/knowledge/init?force=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ❌ 避免做法
|
||||
|
||||
1. **不检查响应就认为成功**:
|
||||
- 始终检查 `failed` 字段
|
||||
- 查看 `details` 了解具体失败原因
|
||||
|
||||
2. **频繁使用 force=true**:
|
||||
- 会重复插入数据(违反唯一约束)
|
||||
- 建议先清理数据库,再使用 force
|
||||
|
||||
3. **不检查文档格式就导入**:
|
||||
- 先手动验证 frontmatter 格式
|
||||
- 确保必填字段完整
|
||||
|
||||
---
|
||||
|
||||
## 相关文档
|
||||
|
||||
- **知识库使用指南**:`mvp/architecture/knowledge-retrieval-usage.md`
|
||||
- **知识库架构**:`mvp/architecture/knowledge-retrieval-architecture.md`
|
||||
- **Executor Prompt**:`src/main/resources/prompts/executor-prompt.md`
|
||||
Reference in New Issue
Block a user