feat(auto-reply): 优化自动回复逻辑和知识库功能
- 将默认回复详细程度从"detailed"调整为"medium",前后端保持一致 - 新增话题切换检测逻辑,当用户主动要求换话题时提供引导回复 - 优化上下文处理机制,仅在指代型追问时注入历史对话,避免模型复读旧内容 - 改进知识库检索逻辑,区分自包含问题和指代型问题的上下文需求 - 完善知识库完整性指令,确保回复详细程度与知识展开程度一致 - 重构知识库重建逻辑,支持递归扫描子目录中的文件,修复索引为空的问题 - 增强素材匹配算法,引入强信号检测机制,避免仅凭模糊匹配误发素材 - 新增素材开场白AI生成功能,支持图片、视频、文档等类型智能描述 - 改进知识库重建通知,显示具体的文件数、分片数及失败统计信息
This commit is contained in:
@@ -71,6 +71,53 @@ func TestRebuildKnowledgeIndexCountsOnlyRootKnowledgeFiles(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRebuildKnowledgeIndexScansSubdirectories 锁住递归扫描行为:
|
||||
// 知识库按分类分文件夹组织时(文件在子目录里),重建必须把子目录里的文件
|
||||
// 一并索引。这是“重置索引后向量仍为空”那个问题的根因回归测试。
|
||||
func TestRebuildKnowledgeIndexScansSubdirectories(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
// 根目录故意不放任何知识文件,全部放进多层子目录。
|
||||
files := map[string]string{
|
||||
filepath.Join("01_产品", "数控机床", "VMC850规格.md"): "VMC850 立式加工中心,主轴转速 8000rpm。",
|
||||
filepath.Join("03_售后", "故障排查", "常见故障.md"): "报警 E01 表示伺服过载,请检查负载。",
|
||||
filepath.Join("readme.txt"): "", // 空文件,应进 FailedFiles 不计入 FileCount
|
||||
}
|
||||
for rel, content := range files {
|
||||
full := filepath.Join(dir, rel)
|
||||
if err := os.MkdirAll(filepath.Dir(full), 0755); err != nil {
|
||||
t.Fatalf("mkdir for %s: %v", rel, err)
|
||||
}
|
||||
if err := os.WriteFile(full, []byte(content), 0644); err != nil {
|
||||
t.Fatalf("write %s: %v", rel, err)
|
||||
}
|
||||
}
|
||||
|
||||
cfg := config.NewDefaultAutoReplyConfig()
|
||||
cfg.Knowledge.Directory = dir
|
||||
cfg.Knowledge.IndexPath = filepath.Join(dir, "index.json")
|
||||
cfg.Retrieval.EmbeddingIndexPath = filepath.Join(dir, "embedding_index.json")
|
||||
engine := testAutoReplyEngine(cfg)
|
||||
|
||||
idx, err := engine.rebuildKnowledgeIndex()
|
||||
if err != nil {
|
||||
t.Fatalf("rebuildKnowledgeIndex failed: %v", err)
|
||||
}
|
||||
if idx.FileCount != 2 {
|
||||
t.Fatalf("expected 2 indexed files from subdirectories, got %d (chunks=%d failed=%v)", idx.FileCount, len(idx.Chunks), idx.FailedFiles)
|
||||
}
|
||||
if len(idx.Chunks) == 0 {
|
||||
t.Fatal("expected chunks from subdirectory files, got none")
|
||||
}
|
||||
// 确认子目录文件的相对路径作为 Source 被正确记录(用 / 分隔)。
|
||||
sources := make(map[string]bool)
|
||||
for _, chunk := range idx.Chunks {
|
||||
sources[chunk.Source] = true
|
||||
}
|
||||
if !sources["01_产品/数控机床/VMC850规格.md"] {
|
||||
t.Fatalf("expected nested source path recorded, got sources=%v", sources)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsePDFKnowledgeFileExtractsTextLayer(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "text.pdf")
|
||||
writeMinimalTextPDF(t, path, "AgentBox PDF content 123")
|
||||
|
||||
Reference in New Issue
Block a user