ax_rd
2 hours ago 60eb89c12ee0661785395bff90940204b16dcb3a
docs: e2e 验证脚本 + README 更新(增量同步/explore/构建要求)
1 files added
1 files modified
129 ■■■■ changed files
README.md 89 ●●●● patch | view | raw | blame | history
scripts/e2e-verify.sh 40 ●●●●● patch | view | raw | blame | history
README.md
@@ -7,8 +7,10 @@
- ✅ **Vault 解析器**:解析 Obsidian frontmatter、标签、实体、wikilinks
- ✅ **知识图谱构建**:文件 → 节点,标签/实体/wikilinks → 边
- ✅ **SQLite 存储**:高效持久化,支持增量更新
- ✅ **FTS5 全文搜索**:基于 SQLite FTS5 的快速搜索
- ✅ **图谱评分算法**:考虑标签、实体、wikilinks 权重
- ✅ **FTS5 全文搜索**:基于 SQLite FTS5 的快速搜索(ASCII 走 FTS5、CJK 走 LIKE 双通道)
- ✅ **图谱评分算法**:文本位置分 + RWR 随机游走图质量双信号加权
- ✅ **长中文词召回**:>3 字符 CJK 词自动 bigram 展开
- ✅ **explore 命令**:按字节预算直出原文段落(agent 一次性上下文)
- ✅ **多种输出格式**:表格、JSON
- ✅ **内容返回**:`--with-content` 返回完整文件内容
- ✅ **关联链接**:`--with-links` 返回 wikilink 关联文档
@@ -28,6 +30,16 @@
**注意**:需要 CGO 和 FTS5 支持。
## 构建要求
go-sqlite3 需要系统 SQLite 开启 FTS5,构建时必须显式传入 CGO 标志(`make build` 已内置):
```bash
CGO_CFLAGS="-DSQLITE_ENABLE_FTS5" CGO_LDFLAGS="-lm" go build
# 或
make build
```
## 使用方法
### 搜索
@@ -58,11 +70,34 @@
kb-cli search 充装 --top 5
```
**双通道检索**:ASCII 词走 FTS5,CJK 词走 LIKE(title/aliases/content/tags 四列)。FTS5 unicode61 把连续中文当整串单 token,多字符中文词 MATCH 匹配不到,必须走 LIKE。长中文词(>3 字符)自动做 bigram 滑动展开(如「电子秤补气失败」→ 电子/子秤/秤补/补气/气失/失败),bigram 命中按扩展词档计权。
**排序双信号**:`最终分 = 文本位置分 × TextWeight + RWR 随机游走图质量 × (1-TextWeight)`(TextWeight 缺省 0.5,可配 config.yaml);草稿态/待审阅板块降权 0.6。
### 探索(explore)
面向 agent 的一次性上下文获取:按字节预算直出相关文档的**原文段落**(整段不截半句),并附关联清单(wikilinks)与悬空链接提示,agent 无需再读文件。
```bash
# 默认预算 16000 字节、Top 5 篇(均可配 config.yaml explore 节)
kb-cli explore "电子秤补气失败"
# 自定义预算与文档数
kb-cli explore "补气失败" --budget 8000 --top 3
# JSON 输出
kb-cli explore "补气失败" --json
```
**与 search 的分工**:`search` 返回文档列表(路径/标题/板块/得分,供浏览定位);`explore` 直接按预算返回命中文档的原文段落(供 agent 一次性获取上下文)。
### 索引管理
```bash
# 构建/重建索引
# 构建索引:默认增量对账同步(按 mtime/size 比对,只处理新增/修改/删除的文件),
# --force 全量重建
kb-cli index build
kb-cli index build --force
# 查看索引状态
kb-cli index status
@@ -78,6 +113,21 @@
kb-cli git sync
```
### 知识图谱
```bash
# 图谱统计(节点数、边数、关系类型分布)
kb-cli graph stats
# 查询节点的关联关系
kb-cli graph query 补气
# 查找与关键词相关的节点
kb-cli graph related 补气 --top 10
```
**provenance 标注**:每条边带 `provenance` 字段标注关系来源类型:`tag`(frontmatter 标签)、`entity`(正文实体)、`exact`/`fuzzy`(wikilink 精确/模糊匹配)。`graph query` 的边数据(含 `--json` 输出)携带该字段;悬空补全的 wikilink 边按匹配方式标注 `exact`/`fuzzy`。`graph related` 只输出节点级信息(路径/板块/标签/关联度),不含边 provenance。
### 全局选项
```bash
@@ -92,8 +142,10 @@
├── cmd/              # CLI 命令
│   ├── root.go       # 根命令
│   ├── search.go     # search 命令
│   ├── explore.go    # explore 命令
│   ├── index.go      # index 命令
│   └── rebuild.go    # 索引重建逻辑
│   ├── graph.go      # graph 命令
│   └── rebuild.go    # 索引构建逻辑
├── internal/
│   ├── vault/        # Vault 解析器
│   │   ├── parser.go
@@ -101,27 +153,38 @@
│   │   └── sections.go
│   ├── graph/        # 知识图谱
│   │   ├── model.go
│   │   └── builder.go
│   │   ├── builder.go
│   │   └── rwr.go    # RWR 随机游走图质量
│   ├── index/        # SQLite 存储
│   │   ├── sqlite.go
│   │   ├── fts.go
│   │   └── cache.go
│   │   ├── fts.go    # 双通道检索(FTS5 + LIKE)
│   │   ├── reconcile.go  # 增量对账
│   │   ├── migrations.go # schema 迁移
│   │   └── graphload.go  # RWR 邻接加载
│   ├── search/       # 搜索引擎
│   │   ├── engine.go
│   │   ├── explore.go    # explore 段落直出
│   │   ├── expand.go     # CJK bigram 展开(search/explore 共享)
│   │   └── scorer.go
│   ├── llm/          # LLM 配置
│   ├── classify/     # 实体/标签分类
│   ├── draft/        # 草稿入库
│   ├── review/       # 草稿预览
│   └── output/       # 输出格式化
│       └── formatter.go
├── scripts/
│   └── e2e-verify.sh # 端到端验证脚本
└── main.go
```
## 评分算法
搜索结果评分考虑:
- **FTS5 rank**:全文搜索相关性
- **标签匹配**:标签权重 2.0
- **实体匹配**:实体权重 1.5
- **Wikilinks**:引用关系权重 1.2
- **扩展词加成**:提升相关实体权重
搜索结果按**双信号加权**排序:
- **文本位置分**:路径/标题/板块/别名/内容命中计权(位置权重不同,别名按 title 档;实体词降权 1/5,通用词降权 1/3)
- **RWR 图质量**:随机游走(Personalized PageRank),种子 = 检索候选前 20,体现节点在知识图谱中的中心性
- **合并**:`最终分 = 归一化文本分 × TextWeight + RWR × (1-TextWeight)`,TextWeight 缺省 0.5(config.yaml 可配)
- **降权**:草稿态(草稿/待确认/跟进中)与「待审阅」板块 ×0.6
## 开发
scripts/e2e-verify.sh
New file
@@ -0,0 +1,40 @@
#!/bin/bash
# 端到端验证(对标 spec 测试计划第 2 节)
set -e
export CGO_CFLAGS="-DSQLITE_ENABLE_FTS5"
export CGO_LDFLAGS="-lm"
VAULT="${1:-$HOME/rag-lpg-obsidian}"
cd "$(dirname "$0")/.."
go build -o /tmp/kb-cli-e2e .
echo "=== 1. 全量重建基准 ==="
/tmp/kb-cli-e2e index build --vault "$VAULT" --force 2>&1 | tail -1
echo "=== 2. 增量同步耗时 ==="
time /tmp/kb-cli-e2e index build --vault "$VAULT" 2>&1 | tail -1
echo "=== 3. 未 commit 编辑可见性 ==="
mkdir -p "$VAULT/笔记"
TESTFILE="$VAULT/笔记/e2e-test-$(date +%s).md"
printf -- "---\ntitle: e2e测试\ntags: [补气]\n---\ne2e 补气测试内容\n" > "$TESTFILE"
/tmp/kb-cli-e2e search e2e --vault "$VAULT" --top 3 2>&1 | grep -q "e2e测试" && echo "PASS: 未commit编辑可见" || echo "FAIL: 未commit编辑不可见"
rm -f "$TESTFILE"
/tmp/kb-cli-e2e index build --vault "$VAULT" 2>/dev/null
echo "=== 4. CJK 召回质量(补气应命中多条)==="
# 适配说明:brief 原 grep 模式 ^文档/\|^FAQ/\|^知识/ 会漏掉「笔记/」等其它板块的结果行,
# 实际输出结果行统一为「板块/…/xxx.md <标题>…」(行首即板块前缀、以 .md 结尾),
# 故按「行首路径以 .md 结尾」计数(以实际输出为准的最小适配)。
N=$(/tmp/kb-cli-e2e search 补气 --vault "$VAULT" --top 10 2>/dev/null | grep -cE '^[^[:space:]]+\.md[[:space:]]' || true)
echo "补气 命中 $N 条 (期望 >= 5)"
if [ "$N" -ge 5 ]; then echo "PASS: CJK 召回 >= 5"; else echo "FAIL: CJK 召回不足"; fi
echo "=== 5. explore 预算内 ==="
BYTES=$(/tmp/kb-cli-e2e explore "电子秤补气失败" --vault "$VAULT" --top 3 2>/dev/null | wc -c)
echo "explore 输出 ${BYTES} 字节 (上限 32000+尾注)"
if [ "$BYTES" -le 32200 ]; then echo "PASS: explore 预算内"; else echo "FAIL: explore 超预算"; fi
echo "=== 6. 悬空补全 ==="
/tmp/kb-cli-e2e graph stats --vault "$VAULT" 2>&1 | head -5
echo "=== e2e 验证完成 ==="