编写未来计划表
This commit is contained in:
@@ -26,7 +26,7 @@
|
|||||||
"mrr": [], # Mean Reciprocal Rank: 倒数排名分数,正确答案排得越靠前,分数越高
|
"mrr": [], # Mean Reciprocal Rank: 倒数排名分数,正确答案排得越靠前,分数越高
|
||||||
"latency": [] # 响应耗时
|
"latency": [] # 响应耗时
|
||||||
```
|
```
|
||||||
3. 搜索逻辑和问题分类:目前参考一些主流的做法,用户输入后先过一个LLM对问题进行拆分和分类,然后传入对应的知识库参数task_id进行对应的检索
|
3. 搜索逻辑和问题分类:尚未实现,目前参考一些主流的做法,用户输入后先过一个LLM对问题进行拆分和分类,然后传入对应的知识库参数task_id进行对应的检索
|
||||||
4. RAG逻辑:混合检索,使用向量和关键词混合检索,此处进行粗筛,数据层返回后在业务层调用 gte-rerank 模型进行重排,最后返回请求
|
4. RAG逻辑:混合检索,使用向量和关键词混合检索,此处进行粗筛,数据层返回后在业务层调用 gte-rerank 模型进行重排,最后返回请求
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@@ -34,8 +34,10 @@
|
|||||||
keyword_score = func.ts_rank(self.db.chunks.c.content_tsvector, keyword_query) # 计算关键词相似度
|
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")# 计算最终分数
|
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服务调用,搜索逻辑,问题分类,流程架构设计,场景假设
|
切割逻辑,准确率定义,归结资料,测试设计,mcp服务调用,搜索逻辑,问题分类,流程架构设计,场景假设
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ class Settings(BaseSettings):
|
|||||||
系统配置类
|
系统配置类
|
||||||
自动读取环境变量或 .env 文件
|
自动读取环境变量或 .env 文件
|
||||||
"""
|
"""
|
||||||
|
CANDIDATE_NUM: int = 10
|
||||||
|
|
||||||
DB_USER: str
|
DB_USER: str
|
||||||
DB_PASS: str
|
DB_PASS: str
|
||||||
DB_HOST: str
|
DB_HOST: str
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ async def auto_process(req: AutoProcessRequest, bg_tasks: BackgroundTasks):
|
|||||||
@router.post("/search")
|
@router.post("/search")
|
||||||
async def search_smart(req: TextSearchRequest):
|
async def search_smart(req: TextSearchRequest):
|
||||||
try:
|
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)
|
return make_response(1, res.pop("msg", "Success"), res)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return make_response(0, str(e))
|
return make_response(0, str(e))
|
||||||
@@ -13,7 +13,6 @@ class AddUrlsRequest(BaseModel):
|
|||||||
task_id: int
|
task_id: int
|
||||||
urls_obj: dict
|
urls_obj: dict
|
||||||
|
|
||||||
# schemas.py
|
|
||||||
class CrawlResult(BaseModel):
|
class CrawlResult(BaseModel):
|
||||||
source_url: str
|
source_url: str
|
||||||
chunk_index: int # 新增字段
|
chunk_index: int # 新增字段
|
||||||
@@ -31,11 +30,6 @@ class SearchRequest(BaseModel):
|
|||||||
query_embedding: dict
|
query_embedding: dict
|
||||||
limit: Optional[int] = 5
|
limit: Optional[int] = 5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ... (保留原有的 Schema: RegisterRequest, AddUrlsRequest 等) ...
|
|
||||||
|
|
||||||
# === V2 New Schemas ===
|
# === V2 New Schemas ===
|
||||||
class AutoMapRequest(BaseModel):
|
class AutoMapRequest(BaseModel):
|
||||||
url: str
|
url: str
|
||||||
@@ -47,4 +41,4 @@ class AutoProcessRequest(BaseModel):
|
|||||||
class TextSearchRequest(BaseModel):
|
class TextSearchRequest(BaseModel):
|
||||||
query: str # 用户直接传文字,不需要传向量了
|
query: str # 用户直接传文字,不需要传向量了
|
||||||
task_id: Optional[int] = None
|
task_id: Optional[int] = None
|
||||||
limit: Optional[int] = 5
|
return_num: Optional[int] = 5
|
||||||
@@ -152,7 +152,7 @@ class CrawlerService:
|
|||||||
|
|
||||||
# 2. 计算粗排召回数量
|
# 2. 计算粗排召回数量
|
||||||
# 逻辑:至少召回 50 个,如果用户要很多,则召回 10 倍
|
# 逻辑:至少召回 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. 执行混合检索 (粗排)
|
# 3. 执行混合检索 (粗排)
|
||||||
coarse_results = data_service.search(
|
coarse_results = data_service.search(
|
||||||
|
|||||||
62
docs/开发计划.md
Normal file
62
docs/开发计划.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# 下一步开发计划
|
||||||
|
|
||||||
|
## 2025.1.13
|
||||||
|
|
||||||
|
1. 知识库RAG
|
||||||
|
测试相关资料参考链接: <https://1988251901502969000zhuanlan.zhihu.com/p/>
|
||||||
|
|
||||||
|
- [ ] 参照主流知识库架构增减修改当前知识库字段
|
||||||
|
- [ ] 根据主流RAG测试要求完善知识库检索测试
|
||||||
|
- [ ] 开发LLM输出测试
|
||||||
|
- [ ] 横向对比不同检索方法或模型下的测试效果
|
||||||
|
2. 后端封装backend
|
||||||
|
|
||||||
|
1. v2API全面增补,废弃v1API,修改data_service.py里为v1保留的旧接口。
|
||||||
|
预期实现效果:
|
||||||
|
- [ ] 添加任务
|
||||||
|
- [ ] 查询任务
|
||||||
|
- [ ] 执行任务
|
||||||
|
- [ ] 获取任务状态
|
||||||
|
- [ ] 获取任务结果
|
||||||
|
- [ ] 知识库搜索
|
||||||
|
2. 包装成MCP
|
||||||
|
|
||||||
|
3. dify节点
|
||||||
|
|
||||||
|
- [ ] 完成dify的LLM输出工具,主要负责处理搜索逻辑和问题分类,调用api,发布工具。
|
||||||
|
也可能直接在backend里全部实现,直接集成到bot里
|
||||||
|
|
||||||
|
4. firecrawl与替代方案调研
|
||||||
|
|
||||||
|
1. firecrawl付费方案
|
||||||
|
- 常规订阅链接: <https://www.firecrawl.dev/pricing>
|
||||||
|
注意: 此链接下均是按时间订阅的,每月限制额度, 可额外购买, 但是考虑到客户使用的时候可能会固定时间集中使用(**采集新wiki, 更新旧wiki**)
|
||||||
|
- 企业订阅方案: 需要联系firecrawl订制
|
||||||
|
2. firecrawl开源方案
|
||||||
|
- 开源github链接: <https://github.com/mendableai/firecrawl>
|
||||||
|
- 优劣对比
|
||||||
|
|
||||||
|
| 对比维度 | 开源版 (Self-hosted) | 云服务版 (Cloud / SaaS) | 核心差异说明 |
|
||||||
|
| :-------------------------- | :------------------------------------------------------------- | :-------------------------------------------------------------- | :------------------------------------------------------------------ |
|
||||||
|
| **部署方式** | 🐳 **Docker 自托管**<br>需自行配置服务器环境 | ☁️ **开箱即用**<br>注册 API Key 即可调用 | 云版省去了复杂的环境搭建过程。 |
|
||||||
|
| **成本** | 🆓 **软件免费**<br>需支付服务器/带宽费用 | 💰 **订阅制**<br>按 Credits (页数) 计费,有免费额度 | 量大且有闲置服务器时开源版更省钱;量小或追求稳定时云版更划算。 |
|
||||||
|
| **反爬虫绕过**<br>(Proxies) | ❌ **弱 / 需自行配置**<br>默认使用本机 IP,易被 Cloudflare 拦截 | ✅ **强 / 内置智能代理**<br>自动轮换 IP,擅长绕过 WAF 和人机验证 | **这是最大的区别。** 云版包含商业代理池成本,开源版需你自己买代理。 |
|
||||||
|
| **维护难度** | 🛠 **高**<br>需维护 Redis、队列、无头浏览器更新 | ☕ **零**<br>官方团队维护基础设施 | 开源版遇到浏览器崩溃或内存泄漏需自己修。 |
|
||||||
|
| **并发与性能** | ⚠️ **受限于硬件**<br>取决于你的服务器配置 | 🚀 **弹性扩容**<br>支持高并发,速度通常更快 | 云版对并行抓取做了优化。 |
|
||||||
|
| **JS 渲染** | ✅ **支持**<br>需配置 Playwright/Puppeteer | ✅ **支持**<br>默认优化,加载更稳定 | 两者核心引擎相同,但云版资源分配更合理。 |
|
||||||
|
| **数据隐私** | 🔒 **高 (本地化)**<br>数据不经过第三方服务器 | ☁️ **中**<br>数据需传输至 Firecrawl 服务器处理 | 对数据合规性要求极高的场景(如金融/医疗)首选开源版。 |
|
||||||
|
| **适用场景** | 极客折腾、内网抓取、低频低难度网站、数据极度敏感 | 商业项目、大规模抓取、高难度网站 (有反爬)、追求稳定性 | |
|
||||||
|
|
||||||
|
3. 自主研发爬虫
|
||||||
|
1. 反爬机制: 维基百科对IP有访问频率限制, 且有验证码, 需自行处理
|
||||||
|
2. 动态内容: 维基百科有很多动态内容, 如表格, 图片等, 需自行处理, 如使用Selenium等工具模拟浏览器行为
|
||||||
|
|
||||||
|
**Firecrawl方案和替代评估总结**
|
||||||
|
假设客户的产品需求是: 从不同的网站爬取文档制成知识库, 并且需要定期维护, 那么其实只有在爬取新的站点和维护旧的站点的时候会集中使用firecrawl的额度, 主要特点是**使用时间集中**且**使用时段内额度需求量很大**以及**优先要保证爬虫模块的稳定性**
|
||||||
|
因此最推荐的方案是: 定时采购额度, 但是考虑到常规的订阅只有按时间计费, 而客户的需求是**定期维护**, 而**按使用额度计费, 即企业协商订阅**的方案是最符合客户需求的.
|
||||||
|
|
||||||
|
| 类别 | 成本 | 困难 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 闭源版 | 购买定制服务, 如果企业长期话成本可能几千? 按年也就一年左右的量够用了 | 用起来很顺手, 目前的接口返回值基本能满足开发需求 |
|
||||||
|
| 开源版 | 需要准备IP池之类的反爬机制, 需要为IP代理付费 | 配置和学习相关的运营维护 |
|
||||||
|
| 自主研发 | 除了研发的时间精力外, 也必需IP池的购买 | 高 |
|
||||||
Reference in New Issue
Block a user