feat(rag): 大文件 RAG 做深 —— 并发入库/图谱窗口化 + Bleve落盘 + file_id治理
几十万字文件从"广而浅"到准生产级: - 向量化串行→并发分批保序(embedAll);几十万字上千块快数倍 - 图谱整篇喂LLM(爆上下文只抽开头)→窗口化并发抽(extractGraphWindowed), 全覆盖;窗口/封顶/并发 env 可配;图谱可单配便宜模型(GRAPH_CHAT_*,未配回退主chat) - Bleve 内存索引(重启即丢、三路退两路)→落盘 scorch(env BLEVE_PATH,失败退内存兜底) - 下游键改稳定 file_id:Neo4j 关系打 file_id(实体仍 kb+name 共享); 新增 kb_delete 工具 + Engine.DeleteDoc 级联删 Milvus/Bleve/Neo4j - 单测:窗口化/去重/env可配/落盘持久/图谱模型回退 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,9 @@ import "testing"
|
||||
// TestBleve_ChineseSearch 钉死中文全文检索:CJK 分词器让"星云一号的总设计师"能命中含
|
||||
// "星云一号""总设计师"的中文块。修复前默认标准分词器把整段中文当一个 token → 永远 0 命中。
|
||||
func TestBleve_ChineseSearch(t *testing.T) {
|
||||
t.Setenv("BLEVE_PATH", t.TempDir()+"/bleve") // 隔离落盘索引,测试互不污染
|
||||
b := openBleve()
|
||||
defer b.close()
|
||||
if !b.ready() {
|
||||
t.Skip("bleve 不可用")
|
||||
}
|
||||
@@ -39,6 +41,26 @@ func TestQueryNgrams(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestBleve_PersistsAcrossReopen 钉死落盘:写入→关闭→同路径重开,数据仍在。
|
||||
// 修复"NewMemOnly 进程重启即丢、三路静默退化两路"的回归——这是 P0 的核心验收。
|
||||
func TestBleve_PersistsAcrossReopen(t *testing.T) {
|
||||
t.Setenv("BLEVE_PATH", t.TempDir()+"/bleve")
|
||||
b1 := openBleve()
|
||||
if !b1.ready() {
|
||||
t.Skip("bleve 不可用")
|
||||
}
|
||||
if err := b1.index("kp", "d1", []string{"持久化测试:龙渊号探测器由总师陈思远负责。"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b1.close() // 模拟进程退出(落盘刷盘)
|
||||
|
||||
b2 := openBleve() // 模拟重启:同路径重开
|
||||
defer b2.close()
|
||||
if hits := b2.search("kp", "龙渊号探测器", 5); len(hits) == 0 {
|
||||
t.Fatal("重开后应仍能检索到(落盘持久),got 0 —— 退回内存了?")
|
||||
}
|
||||
}
|
||||
|
||||
func contains(s, sub string) bool {
|
||||
return len(sub) == 0 || (len(s) >= len(sub) && indexOf(s, sub) >= 0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user