ai_xiaopei
9 days ago b7947528d296608f48c2799cef6b535f5bd5c665
fix: 使用 Makefile 编译确保 FTS5 支持

- 统一使用 make build 编译,避免忘记 -tags fts5
- 修复 search 命令 no such module: fts5 错误
- 重建索引测试通过(768 节点, 3731 边)
1 files modified
1 files added
414 ■■■■■ changed files
bin/kb-cli patch | view | raw | blame | history
docs/superpowers/specs/2026-07-26-kb-cli-draft-integration-design.md 414 ●●●●● patch | view | raw | blame | history
bin/kb-cli
Binary files differ
docs/superpowers/specs/2026-07-26-kb-cli-draft-integration-design.md
New file
@@ -0,0 +1,414 @@
# kb-cli 草稿录入集成设计文档
**日期**: 2026-07-26
**状态**: 设计中
**版本**: v0.4.0
## 背景
当前知识库草稿录入依赖 Python 脚本 `draft-intake.py`,需要 Hermes Agent 手动调用。本次设计将草稿录入功能集成到 kb-cli,实现:
1. AI 生成草稿标题和正文
2. kb-cli 自动提取 tags(调用本地 LLM)
3. kb-cli 自动搜索相关文档并生成合并指示
4. 通过知识图谱创建 wikilinks
## 目标
- **简化流程**: 一条命令完成草稿创建 + tags 提取 + 合并指示生成
- **智能标签**: 使用本地 LLM 提取问题匹配型 tags + 扩展词
- **自动关联**: 基于 tags 搜索知识库,生成合并指示和 wikilinks
- **批量重建**: 支持为现有文档批量重建 tags
## 核心流程
```
草稿内容 → LLM 生成 tags → kb-cli search(tags) → 搜索到 top3 文档 → LLM 生成合并指示
```
### 详细步骤
1. **LLM 提取 tags + related_docs**
   - 输入:草稿内容
   - 输出:5-10 个 tags + 0-5 个相关文档标题
   - tags 类型:核心问题标签 + 扩展词 + 平台/设备标签
2. **kb-cli search(tags)**
   - 使用 tags 作为关键词搜索知识库
   - 返回 top3 相关文档
3. **LLM 生成合并指示**
   - 输入:草稿内容 + top3 文档
   - 输出:merge.md(包含合并建议 + 理由)
4. **创建 wikilinks**
   - 通过 graph 匹配 related_docs 对应的节点
   - 创建 wikilink edges
5. **写入文件**
   - draft.md:包含 frontmatter(tags)+ 正文
   - merge.md:合并指示
## 命令设计
### 1. draft create
创建草稿,自动生成 tags 和合并指示。
```bash
kb-cli draft create --type 售后 --title "标题" --content-file /path/to/content.md
```
**参数**:
- `--type`: 草稿类型(售后/产品/运营/行业/TAPD)
- `--title`: 草稿标题
- `--content-file`: 草稿正文文件路径
- `--source`: 来源标识(可选)
- `--force`: 强制创建,跳过重复检查
**流程**:
1. 读取 content-file 内容
2. 调用 LLM 提取 tags + related_docs
3. 使用 tags 搜索知识库,获取 top3 文档
4. 调用 LLM 生成合并指示(基于 top3 文档)
5. 检查待审阅区是否已存在相同标题的草稿
6. 创建目录结构:`待审阅/{类型}/NNN-YYYYMMDD-标题/`
7. 写入 draft.md(包含 frontmatter + 正文)
8. 写入 merge.md(合并指示)
9. 通过 graph 匹配 related_docs,创建 wikilink edges
### 2. tags rebuild
批量重建现有文档的 tags。
```bash
kb-cli tags rebuild [--vault=<路径>] [--dry-run] [--limit=100]
```
**参数**:
- `--vault`: 知识库路径(默认 ~/aisim/note/001/笔记001)
- `--dry-run`: 仅预览,不实际写入
- `--limit`: 限制处理文档数量(默认 100)
**流程**:
1. 扫描知识库所有 .md 文件
2. 对每个文件:
   - 读取内容
   - 调用 LLM 提取 tags
   - 更新 frontmatter 中的 tags 字段
   - 重建索引(更新 nodes 表的 tags 字段)
3. 输出统计:处理文件数、更新 tags 数
## LLM 配置
复用 `generate-merge-hint.py` 的配置:
- **API**: `http://192.168.3.246:1127/v1/chat/completions`
- **Model**: `qwen3.6-35b-a3b`
- **参数**: temperature=0.3, max_tokens=2000, enable_thinking=False
### Prompt 设计
#### 提取 tags + related_docs
```
分析以下知识库草稿,提取:
1. tags(5-10个):
   - 核心问题标签(如"充不进气"、"档案下载失败")
   - 扩展词(不同人可能的描述,如"充气慢"、"进气不足")
   - 平台/设备标签(如"电子秤平台"、"智能枪")
2. related_docs(0-5个):相关文档标题(用于创建链接)
输出 JSON:
{
  "tags": ["充不进气", "充气慢", "进气不足", "智能枪", "电子秤平台"],
  "related_docs": ["智能枪通气杆卡住漏气", "角阀充装功率不足"]
}
草稿内容:
{content}
```
#### 生成合并指示
```
你是一个知识库管理助手。请判断以下草稿与哪些知识库文档相关。
## 草稿内容
{draft_content}
## 候选文档(Top 3)
1. 标题: {title1}, 路径: {path1}, 相关度: {score1}
2. 标题: {title2}, 路径: {path2}, 相关度: {score2}
3. 标题: {title3}, 路径: {path3}, 相关度: {score3}
## 任务
请分析草稿与每个候选文档的相关性,输出 JSON 格式:
{
  "recommendation": {
    "action": "merge|new|split",
    "target": "目标路径(如果 action=merge)",
    "reason": "判断理由",
    "confidence": "high|medium|low"
  },
  "analysis": [
    {
      "path": "文档路径",
      "relevance": "high|medium|low",
      "reason": "相关性说明"
    }
  ]
}
判断标准:
- action=merge: 草稿内容与某个候选文档高度相关,应该合并
- action=new: 草稿内容是全新的,应该新建文档
- action=split: 草稿内容包含多个独立主题,应该拆分
- confidence=high: 判断很确定
- confidence=medium: 判断比较确定
- confidence=low: 判断不太确定
只输出 JSON,不要其他内容。
```
## 文件结构
```
待审阅/
├── 售后提取/
│   ├── 001-20260726-充不进气问题/
│   │   ├── draft.md      # 草稿内容(包含 tags)
│   │   └── merge.md      # 合并指示
│   └── 002-20260726-档案下载失败/
│       ├── draft.md
│       └── merge.md
├── 产品提取/
├── 运营提取/
├── TAPD提取/
└── counter.json          # 编号计数器
```
### draft.md 格式
```markdown
---
title: "充不进气问题"
type: "售后"
status: 待确认
draft: true
source: "售后诊断"
tags: [充不进气, 充气慢, 进气不足, 智能枪, 电子秤平台]
created: 2026-07-26 10:30:00
---
## 问题描述
客户反馈充装时充不进气,或充气速度很慢...
## 排查过程
1. 检查智能枪是否正常连接
2. 检查角阀是否打开
...
## 解决方案
1. 更换智能枪通气杆
2. 清理角阀滤网
...
```
### merge.md 格式
```markdown
---
draft_id: 001-20260726-充不进气问题
generated_at: 2026-07-26 10:35:00
confidence: high
---
## 合并指示
**操作类型**: merge
**目标**: FAQ/充装类/001-智能枪通气杆卡住漏气.md
**理由**: 草稿描述的"充不进气"问题与现有 FAQ 001 高度相关,都是智能枪通气杆问题导致的充气异常
## 依据
### 搜索到的相关文档(Top 3)
1. **智能枪通气杆卡住漏气** (相似度: 0.92)
   - 路径: `FAQ/充装类/001-智能枪通气杆卡住漏气.md`
   - 摘要: 智能枪通气杆卡住导致漏气,影响充装...
2. **角阀充装功率不足** (相似度: 0.78)
   - 路径: `FAQ/充装类/017-角阀充装功率不足.md`
   - 摘要: 角阀供电不足导致充装功率低...
3. **充不进气与老瓶芯片问题** (相似度: 0.75)
   - 路径: `FAQ/充装类/013-充不进气与老瓶芯片问题.md`
   - 摘要: 老瓶芯片兼容性问题导致充不进气...
## LLM 判断
- **FAQ/充装类/001-智能枪通气杆卡住漏气.md**: high - 草稿描述的充气慢、充不进气现象与 FAQ 001 的通气杆卡住问题高度一致
- **FAQ/充装类/017-角阀充装功率不足.md**: medium - 功率不足也会导致充气慢,但根因不同
- **FAQ/充装类/013-充不进气与老瓶芯片问题.md**: medium - 都是充不进气问题,但老瓶芯片是识别问题,不是充气问题
```
## 技术实现
### 依赖
- `github.com/mattn/go-sqlite3` (需要 CGO + FTS5 标签)
- 本地 LLM API(OpenAI 兼容格式)
### 模块设计
#### 1. internal/llm/client.go
LLM 客户端,封装 API 调用。
```go
type Client struct {
    apiBase string
    apiKey  string
    model   string
}
func NewClient(apiBase, apiKey, model string) *Client
func (c *Client) ExtractTags(content string) (*ExtractResult, error)
func (c *Client) GenerateMergeHint(draftContent string, candidates []SearchResult) (*MergeHint, error)
```
#### 2. internal/draft/intake.go
草稿录入逻辑。
```go
type DraftIntake struct {
    vaultPath string
    llmClient *llm.Client
    store     *index.Store
}
func NewDraftIntake(vaultPath string, llmClient *llm.Client, store *index.Store) *DraftIntake
func (d *DraftIntake) CreateDraft(draftType, title, content, source string, force bool) error
func (d *DraftIntake) RebuildTags(limit int, dryRun bool) error
```
#### 3. cmd/draft.go
CLI 命令定义。
```go
var draftCmd = &cobra.Command{
    Use:   "draft",
    Short: "草稿管理",
}
var draftCreateCmd = &cobra.Command{
    Use:   "create",
    Short: "创建草稿",
    RunE:  runDraftCreate,
}
var tagsRebuildCmd = &cobra.Command{
    Use:   "rebuild",
    Short: "重建 tags",
    RunE:  runTagsRebuild,
}
```
## 待解决问题
### 1. FTS5 模块缺失
**问题**: go-sqlite3 编译时未启用 FTS5,导致 `kb-cli search` 报错 `no such module: fts5`
**解决方案**: 编译时添加 CGO 标签
```bash
go build -tags fts5 -o ~/go/bin/kb-cli
```
**验证**:
```bash
kb-cli search 充装
```
### 2. LLM API 配置
**问题**: 需要硬编码 API 地址和密钥,还是从配置文件读取?
**方案**: 从环境变量读取,支持回退到默认值
```go
apiBase := os.Getenv("KB_LLM_API_BASE")
if apiBase == "" {
    apiBase = "http://192.168.3.246:1127/v1"
}
```
## 实现计划
### Phase 1: 修复 FTS5 问题
1. 重新编译 kb-cli,添加 `-tags fts5`
2. 验证 `kb-cli search` 正常工作
### Phase 2: 实现 LLM 客户端
1. 创建 `internal/llm/client.go`
2. 实现 `ExtractTags` 和 `GenerateMergeHint` 方法
3. 编写单元测试
### Phase 3: 实现 draft create 命令
1. 创建 `internal/draft/intake.go`
2. 实现草稿创建逻辑
3. 创建 `cmd/draft.go`,定义 CLI 命令
4. 集成测试
### Phase 4: 实现 tags rebuild 命令
1. 实现批量重建 tags 逻辑
2. 添加 `--dry-run` 支持
3. 集成测试
### Phase 5: 文档与发布
1. 更新 README.md
2. 更新技能文档
3. 发布 v0.4.0
## 风险与缓解
### 风险 1: LLM 输出不稳定
**缓解**:
- 使用 temperature=0.3 降低随机性
- 添加 JSON 解析容错(尝试提取 ```json 代码块)
- 失败时回退到简单模式(只生成 tags,不生成 related_docs)
### 风险 2: tags 质量不高
**缓解**:
- Prompt 明确要求三类 tags(核心问题 + 扩展词 + 平台/设备)
- 提供示例,引导 LLM 输出高质量 tags
- 后续可通过 `tags rebuild` 批量优化
### 风险 3: 合并指示不准确
**缓解**:
- 提供 top3 候选文档,让 LLM 有足够信息判断
- 要求 LLM 输出 confidence 字段,低置信度时提示人工审核
- 保留 merge.md 文件,方便人工修正
## 成功标准
- `kb-cli draft create` 能成功创建草稿,包含 tags 和合并指示
- `kb-cli tags rebuild` 能批量重建现有文档的 tags
- tags 质量满足搜索需求(能匹配用户描述的问题)
- 合并指示准确率达到 80% 以上(high + medium confidence)
## 后续优化
1. **智能分类**: 根据内容自动判断草稿类型(售后/产品/运营)
2. **增量更新**: 只重建 tags 变化的文档,减少 LLM 调用
3. **批量模式**: 支持从文件批量导入草稿(如 CSV、JSON)
4. **Web UI**: 提供 Web 界面管理草稿和审阅流程