diff --git a/docs/cli/ingest.md b/docs/cli/ingest.md index e64678e..f5c491d 100644 --- a/docs/cli/ingest.md +++ b/docs/cli/ingest.md @@ -14,7 +14,6 @@ | ------ | ------ | ------ | ----- | | `--path` | `-i` | 本地文件或目录路径 | 与 `--url` 二选一 | | `--url` | `-u` | 网页 URL 地址 | 与 `--path` 二选一 | -| `--clean` | - | 执行 LLM 清洗 | `False` | | `--no-tag` | - | 跳过打 tag | `False` | | `--verbose` | `-v` | 详细输出 | `False` | | `--json` | - | 输出到 JSON 文件 | stdout(使用时须指定文件路径) | @@ -25,8 +24,8 @@ # 全流程导入 algonotes ingest -i ./my_notes/ -# 从 URL 导入并清洗 -algonotes ingest -u https://cnblogs.com/xxx --clean +# 从 URL 导入(默认自动清洗) +algonotes ingest -u https://cnblogs.com/xxx # 跳过打 tag algonotes ingest -i ./my_notes/ --no-tag @@ -79,7 +78,7 @@ algonotes ingest -i ./my_notes/ --json result.json 导入完成: 3 个文件,耗时 12.3s ``` -> 💡 verbose 模式下,`--clean` 清洗时会实时流式输出清洗内容 +> 💡 verbose 模式下,清洗内容会实时流式输出(网页导入默认启用清洗,本地导入默认不启用) ## 流程 @@ -88,8 +87,8 @@ graph TD A[输入源] -->|-i / -u| B{文件类型} B -->|本地 .md| C[Loader] B -->|网页 URL| D[WebLoader] - D -->|--clean| E[Cleaner] C --> F[Splitter] + D -.->|默认清洗| E[Cleaner] E --> F F -->|--no-tag| G[跳过] F -->|默认| H[Tagger] @@ -153,5 +152,5 @@ graph TD 1. **文件命名**:导入后文件名即唯一标识,平铺存储在 `data/files/` 下 2. **文件名冲突**:同名文件会自动添加时间戳后缀(如 `fenwick_20260616_143022.md`) -3. **网页清洗**:从 URL 导入时,建议使用 `--clean` 清洗网页噪声,要不然可能无法正确分块 +3. **网页清洗**:从 URL 导入时,默认自动执行 LLM 清洗以去除网页噪声;本地导入默认不启用 4. **打 tag**:需要调用 LLM,会增加处理时间,可用 `--no-tag` 跳过 diff --git a/docs/cli/update.md b/docs/cli/update.md index dd9a0ab..cc873b1 100644 --- a/docs/cli/update.md +++ b/docs/cli/update.md @@ -25,7 +25,6 @@ | ------ | ------ | ------ | ------ | | `filename` | - | 笔记文件名(位置参数) | 必填 | | `--file` | - | 新的本地文件路径 | 无 | -| `--clean` | - | 执行 LLM 清洗 | `False` | | `--no-tag` | - | 跳过打 tag | `False` | | `--verbose` | `-v` | 详细输出 | `False` | | `--json` | - | 输出到 JSON 文件 | stdout | @@ -39,9 +38,6 @@ algonotes update content fenwick.md --file ./updated_fenwick.md # 更新 URL 笔记(从原页面重新爬取) algonotes update content cnblogs_xxx.md -# 更新本地笔记并清洗 -algonotes update content fenwick.md --file ./new.md --clean - # 输出到 JSON 文件 algonotes update content fenwick.md --file ./new.md --json result.json ``` @@ -54,8 +50,8 @@ Update success: fenwick.md (13 chunks) ### 更新逻辑 -- **本地笔记**:必须指定 `--file`,根据新文件更新三层存储 -- **URL 笔记**:无需额外参数,从数据库调取原 URL → 重新爬取 → 更新三层存储 +- **本地笔记**:必须指定 `--file`,根据新文件更新三层存储(默认不启用清洗) +- **URL 笔记**:无需额外参数,从数据库调取原 URL → 重新爬取 → 更新三层存储(默认启用清洗) --- @@ -111,16 +107,17 @@ graph TD D -->|否| F{有 source_url?} F -->|否| C F -->|是| G[WebLoader 重新爬取] - E --> H[删除旧向量] - G --> H - H --> I[Splitter 分块] - I -->|--no-tag| J[跳过] - I -->|默认| K[Tagger 提取标签] - K --> L[更新三层存储] - J --> L - L --> M[data/files/] - L --> N[data/sql_db/] - L --> O[data/chroma_db/] + G -.->|默认清洗| H[Cleaner] + E --> I[删除旧向量] + H --> I + I --> J[Splitter 分块] + J -->|--no-tag| K[跳过] + J -->|默认| L[Tagger 提取标签] + L --> M[更新三层存储] + K --> M + M --> N[data/files/] + M --> O[data/sql_db/] + M --> P[data/chroma_db/] ``` ## 依赖模块 diff --git a/prompts/agent_system.md b/prompts/agent_system.md index bb8736b..d1d623a 100644 --- a/prompts/agent_system.md +++ b/prompts/agent_system.md @@ -8,7 +8,7 @@ 2. **检索信息**:使用 search_notes 或 search_by_tags 获取相关信息 3. **查询文件**: 你可以按需通过向量搜索的 source 和 tags 的结果,通过 get_file_content 查询对应文件名的笔记全文 4. **超时判断**:若你多次调用相关工具没有查询到相关结果,为了节省 Token 使用,请你诚实告诉用户没有检索到相应内容,并且尝试用你的内置知识回答问题 -5. **重排序**:调用 rerank_results 对检索结果去重和重排 +5. **重排序**:按需调用 rerank_results, 对检索结果去重和重排 6. **生成答案**:基于重排后的结果给出带溯源引用的竞赛友好答案 ## 可用工具 @@ -16,7 +16,7 @@ - `search_notes(query, top_k)` — 语义搜索个人笔记,query 用关键词形式 - `search_by_tags(keyword)` — 按标签搜索笔记文件名 - `get_file_content(filename)` — 获取某篇笔记的全文 -- `rerank_results(query, docs, top_n)` — 对检索结果去重、重排序。生成答案前必须先调用此工具 +- `rerank_results(query, docs, top_n)` — 对检索结果去重、重排序。 ## 引用格式 @@ -24,9 +24,10 @@ ## 注意事项 -- 收集完所有结果后务必调用 `rerank_results` 再生成答案 +- 收集完所有结果后请注意按需调用 `rerank_results`,当文档数据量*较小*时避免不必要的调用 - 不要编造引用来源 - 在你多次尝试检索后,如果检索结果不足以回答问题,如实告知用户,然后尝试用你的内置知识库回答问题 +- ## 特殊注意点 diff --git a/prompts/clean.md b/prompts/clean.md index 41143f6..98875ad 100644 --- a/prompts/clean.md +++ b/prompts/clean.md @@ -1,8 +1,10 @@ -请帮我清洗一下下面这段文本,去掉无关的网页内容,保留结构化的markdown文本。并且适当调用你的知识储备,使得文章结构完整,语义通顺。如果有涉及到具体算法题,请你保留题号以便于后续检索。 +清洗下面这段网页文本,移除无关的网页内容,保留结构化的 Markdown 文本。适当调用你的知识储备,使得文章结构完整,语义通顺。如果有涉及到具体算法题,请你保留题号以便于后续检索。 输出格式要求: -1. 保留标题、段落、代码块等结构,尤其注意标题的层级,这将直接影响RAG的分块 -2. 去掉导航栏、广告、页脚、侧边栏等非正文内容 -3. 保留正文中的链接和图片引用 -4. 不要输出任何无关内容,比如"以下是清洗后的文本,保留了原始内容的结构化 Markdown 格式:"或者用"```markdown"包裹 -5. 输出必须以一级标题(# 标题)开头,这是RAG分块的必要条件。如果原文没有标题,请根据内容总结一个简洁准确的标题 +1. 输出应该严格保证 Markdown 结构,不得出现非法的 MD 语法。 +2. 保留标题、段落、代码块等原始 Markdown 结构,可以根据内容适当优化 Markdown 结构,尤其注意标题的层级,这将直接影响 RAG 的分块 +3. 移除连续的空行,至多保留一行。 +4. 输出必须以一级标题(# 标题)开头,这是RAG分块的必要条件。如果原文没有标题,请根据内容总结一个简洁准确的标题 +5. 去掉导航栏、广告、页脚、侧边栏等非正文内容 +6. 保留正文中的链接和图片引用 +7. 不要输出任何无关内容,比如 "以下是清洗后的文本,保留了原始内容的结构化 Markdown 格式:" 或者用 "```markdown" 包裹 diff --git a/prompts/tagger.md b/prompts/tagger.md index 9f5cffd..c5134cd 100644 --- a/prompts/tagger.md +++ b/prompts/tagger.md @@ -1,7 +1,3 @@ -# Tag extractor prompt for AlgoNotes RAG - -## Given a note's content, extract algorithm/topic tags for metadata indexing - 从以下算法竞赛笔记中提取 1-5 个标签。 要求: diff --git a/scripts/cli.py b/scripts/cli.py index f6f8f11..d669555 100644 --- a/scripts/cli.py +++ b/scripts/cli.py @@ -50,8 +50,6 @@ def main(): help="本地文件或目录路径") source.add_argument("-u", "--url", help="网页 URL 地址") - p_ingest.add_argument("--clean", action="store_true", - help="执行 LLM 清洗") p_ingest.add_argument("--no-tag", action="store_true", help="跳过打 tag") p_ingest.add_argument("--type", choices=["note", "solution", "template"], @@ -69,8 +67,6 @@ def main(): p_content = u_sub.add_parser("content", help="更新笔记内容(重新处理文件)") p_content.add_argument("filename", help="笔记文件名") p_content.add_argument("--file", type=Path, help="新的本地文件路径") - p_content.add_argument("--clean", action="store_true", - help="执行 LLM 清洗") p_content.add_argument("--no-tag", action="store_true", help="跳过打 tag") p_content.add_argument("-v", "--verbose", action="store_true", @@ -180,18 +176,18 @@ def _run_ingest(args): if args.path: if args.path.is_file(): - result = ingest_local(args.path, clean=args.clean, + result = ingest_local(args.path, tag=tag, verbose=args.verbose, type=note_type, author=author) elif args.path.is_dir(): - results = ingest_locals(args.path, clean=args.clean, + results = ingest_locals(args.path, tag=tag, verbose=args.verbose, type=note_type, author=author) else: print(f"❌ 路径不存在: {args.path}") sys.exit(1) elif args.url: - result = ingest_web(args.url, clean=args.clean, + result = ingest_web(args.url, tag=tag, verbose=args.verbose, type=note_type, author=author) @@ -236,7 +232,6 @@ def _run_update_content(args): result = update_note( args.filename, file_path=args.file, - clean=args.clean, tag=tag, verbose=args.verbose, ) diff --git a/src/ingestion/cleaner.py b/src/ingestion/cleaner.py index ca2da94..c336d8a 100644 --- a/src/ingestion/cleaner.py +++ b/src/ingestion/cleaner.py @@ -25,7 +25,7 @@ def _strip_code_block_wrapper(text: str) -> str: """Strip markdown code block wrapper if LLM added it despite instructions.""" stripped = text.strip() if stripped.startswith("```markdown") and stripped.endswith("```"): - stripped = stripped[len("markdown"):].strip() + stripped = stripped[len("```markdown"):].strip() if stripped.endswith("```"): stripped = stripped[:-3].strip() elif stripped.startswith("```") and stripped.endswith("```"):