From e1a94d4bc7550348eca4c86ba0c1b3a9414bd14e Mon Sep 17 00:00:00 2001 From: QingGang Date: Tue, 13 Jan 2026 17:42:19 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E5=86=99=E6=9C=AA=E6=9D=A5=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++- backend/core/config.py | 2 + backend/routers/v2.py | 2 +- backend/schemas/schemas.py | 8 +--- backend/services/crawler_service.py | 2 +- docs/开发计划.md | 62 +++++++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 docs/开发计划.md diff --git a/README.md b/README.md index ba3337f..125df1b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ "mrr": [], # Mean Reciprocal Rank: 倒数排名分数,正确答案排得越靠前,分数越高 "latency": [] # 响应耗时 ``` -3. 搜索逻辑和问题分类:目前参考一些主流的做法,用户输入后先过一个LLM对问题进行拆分和分类,然后传入对应的知识库参数task_id进行对应的检索 +3. 搜索逻辑和问题分类:尚未实现,目前参考一些主流的做法,用户输入后先过一个LLM对问题进行拆分和分类,然后传入对应的知识库参数task_id进行对应的检索 4. RAG逻辑:混合检索,使用向量和关键词混合检索,此处进行粗筛,数据层返回后在业务层调用 gte-rerank 模型进行重排,最后返回请求 ```python @@ -34,8 +34,10 @@ keyword_score = func.ts_rank(self.db.chunks.c.content_tsvector, keyword_query) # 计算关键词相似度 final_score = (vector_score * 0.7 + func.coalesce(keyword_score, 0) * 0.3).label("score")# 计算最终分数 ``` -5. 产品面向:爬虫获取完整wiki(可无视robots.txt),当前知识库存入和爬虫绑定强,依赖markdown格式存入 +5. 产品面向场景:客户需求爬取几个文档,并长期维护更新,后续需要新增,但是量相对不会太大,firecrawl付费大概不会太贵。爬虫获取完整wiki(可无视robots.txt),当前知识库存入和爬虫绑定强,依赖markdown格式存入 +6. 后续开发:添加旧wiki的更新维护功能。dify增加对后端的封装,做一套搜索逻辑和问题分类的节点,如果不好弄那还是迁回到后端,后端只提供知识库的mcp,bot调用mcp之后,自行调用实现搜索和问题分类 +对比其他检索方法的优势,做一套评测机制标准,评估最终LLM输出的准确度,目前是知识库检索准确度 切割逻辑,准确率定义,归结资料,测试设计,mcp服务调用,搜索逻辑,问题分类,流程架构设计,场景假设 diff --git a/backend/core/config.py b/backend/core/config.py index 30704a8..9240071 100644 --- a/backend/core/config.py +++ b/backend/core/config.py @@ -5,6 +5,8 @@ class Settings(BaseSettings): 系统配置类 自动读取环境变量或 .env 文件 """ + CANDIDATE_NUM: int = 10 + DB_USER: str DB_PASS: str DB_HOST: str diff --git a/backend/routers/v2.py b/backend/routers/v2.py index 981b7a0..2db38b5 100644 --- a/backend/routers/v2.py +++ b/backend/routers/v2.py @@ -24,7 +24,7 @@ async def auto_process(req: AutoProcessRequest, bg_tasks: BackgroundTasks): @router.post("/search") async def search_smart(req: TextSearchRequest): try: - res = crawler_service.search(req.query, req.task_id, req.limit) + res = crawler_service.search(req.query, req.task_id, req.return_num) return make_response(1, res.pop("msg", "Success"), res) except Exception as e: return make_response(0, str(e)) \ No newline at end of file diff --git a/backend/schemas/schemas.py b/backend/schemas/schemas.py index 64617aa..9d95fe1 100644 --- a/backend/schemas/schemas.py +++ b/backend/schemas/schemas.py @@ -13,7 +13,6 @@ class AddUrlsRequest(BaseModel): task_id: int urls_obj: dict -# schemas.py class CrawlResult(BaseModel): source_url: str chunk_index: int # 新增字段 @@ -31,11 +30,6 @@ class SearchRequest(BaseModel): query_embedding: dict limit: Optional[int] = 5 - - - -# ... (保留原有的 Schema: RegisterRequest, AddUrlsRequest 等) ... - # === V2 New Schemas === class AutoMapRequest(BaseModel): url: str @@ -47,4 +41,4 @@ class AutoProcessRequest(BaseModel): class TextSearchRequest(BaseModel): query: str # 用户直接传文字,不需要传向量了 task_id: Optional[int] = None - limit: Optional[int] = 5 \ No newline at end of file + return_num: Optional[int] = 5 \ No newline at end of file diff --git a/backend/services/crawler_service.py b/backend/services/crawler_service.py index 70172af..534940f 100644 --- a/backend/services/crawler_service.py +++ b/backend/services/crawler_service.py @@ -152,7 +152,7 @@ class CrawlerService: # 2. 计算粗排召回数量 # 逻辑:至少召回 50 个,如果用户要很多,则召回 10 倍 - coarse_limit = return_num * 10 if return_num * 10 > 50 else 50 + coarse_limit = return_num * 10 if return_num * 10 > settings.CANDIDATE_NUM else settings.CANDIDATE_NUM # 3. 执行混合检索 (粗排) coarse_results = data_service.search( diff --git a/docs/开发计划.md b/docs/开发计划.md new file mode 100644 index 0000000..15c8bcc --- /dev/null +++ b/docs/开发计划.md @@ -0,0 +1,62 @@ +# 下一步开发计划 + +## 2025.1.13 + +1. 知识库RAG + 测试相关资料参考链接: + + - [ ] 参照主流知识库架构增减修改当前知识库字段 + - [ ] 根据主流RAG测试要求完善知识库检索测试 + - [ ] 开发LLM输出测试 + - [ ] 横向对比不同检索方法或模型下的测试效果 +2. 后端封装backend + + 1. v2API全面增补,废弃v1API,修改data_service.py里为v1保留的旧接口。 + 预期实现效果: + - [ ] 添加任务 + - [ ] 查询任务 + - [ ] 执行任务 + - [ ] 获取任务状态 + - [ ] 获取任务结果 + - [ ] 知识库搜索 + 2. 包装成MCP + +3. dify节点 + + - [ ] 完成dify的LLM输出工具,主要负责处理搜索逻辑和问题分类,调用api,发布工具。 + 也可能直接在backend里全部实现,直接集成到bot里 + +4. firecrawl与替代方案调研 + + 1. firecrawl付费方案 + - 常规订阅链接: + 注意: 此链接下均是按时间订阅的,每月限制额度, 可额外购买, 但是考虑到客户使用的时候可能会固定时间集中使用(**采集新wiki, 更新旧wiki**) + - 企业订阅方案: 需要联系firecrawl订制 + 2. firecrawl开源方案 + - 开源github链接: + - 优劣对比 + + | 对比维度 | 开源版 (Self-hosted) | 云服务版 (Cloud / SaaS) | 核心差异说明 | + | :-------------------------- | :------------------------------------------------------------- | :-------------------------------------------------------------- | :------------------------------------------------------------------ | + | **部署方式** | 🐳 **Docker 自托管**
需自行配置服务器环境 | ☁️ **开箱即用**
注册 API Key 即可调用 | 云版省去了复杂的环境搭建过程。 | + | **成本** | 🆓 **软件免费**
需支付服务器/带宽费用 | 💰 **订阅制**
按 Credits (页数) 计费,有免费额度 | 量大且有闲置服务器时开源版更省钱;量小或追求稳定时云版更划算。 | + | **反爬虫绕过**
(Proxies) | ❌ **弱 / 需自行配置**
默认使用本机 IP,易被 Cloudflare 拦截 | ✅ **强 / 内置智能代理**
自动轮换 IP,擅长绕过 WAF 和人机验证 | **这是最大的区别。** 云版包含商业代理池成本,开源版需你自己买代理。 | + | **维护难度** | 🛠 **高**
需维护 Redis、队列、无头浏览器更新 | ☕ **零**
官方团队维护基础设施 | 开源版遇到浏览器崩溃或内存泄漏需自己修。 | + | **并发与性能** | ⚠️ **受限于硬件**
取决于你的服务器配置 | 🚀 **弹性扩容**
支持高并发,速度通常更快 | 云版对并行抓取做了优化。 | + | **JS 渲染** | ✅ **支持**
需配置 Playwright/Puppeteer | ✅ **支持**
默认优化,加载更稳定 | 两者核心引擎相同,但云版资源分配更合理。 | + | **数据隐私** | 🔒 **高 (本地化)**
数据不经过第三方服务器 | ☁️ **中**
数据需传输至 Firecrawl 服务器处理 | 对数据合规性要求极高的场景(如金融/医疗)首选开源版。 | + | **适用场景** | 极客折腾、内网抓取、低频低难度网站、数据极度敏感 | 商业项目、大规模抓取、高难度网站 (有反爬)、追求稳定性 | | + + 3. 自主研发爬虫 + 1. 反爬机制: 维基百科对IP有访问频率限制, 且有验证码, 需自行处理 + 2. 动态内容: 维基百科有很多动态内容, 如表格, 图片等, 需自行处理, 如使用Selenium等工具模拟浏览器行为 + + **Firecrawl方案和替代评估总结** + 假设客户的产品需求是: 从不同的网站爬取文档制成知识库, 并且需要定期维护, 那么其实只有在爬取新的站点和维护旧的站点的时候会集中使用firecrawl的额度, 主要特点是**使用时间集中**且**使用时段内额度需求量很大**以及**优先要保证爬虫模块的稳定性** + 因此最推荐的方案是: 定时采购额度, 但是考虑到常规的订阅只有按时间计费, 而客户的需求是**定期维护**, 而**按使用额度计费, 即企业协商订阅**的方案是最符合客户需求的. + + | 类别 | 成本 | 困难 | + | --- | --- | --- | + | 闭源版 | 购买定制服务, 如果企业长期话成本可能几千? 按年也就一年左右的量够用了 | 用起来很顺手, 目前的接口返回值基本能满足开发需求 | + | 开源版 | 需要准备IP池之类的反爬机制, 需要为IP代理付费 | 配置和学习相关的运营维护 | + | 自主研发 | 除了研发的时间精力外, 也必需IP池的购买 | 高 |