MaxKB 深度剖析:一套 RAG 智能问答平台的完整技术拆解
【免费下载链接】MaxKB🔥 MaxKB is an open-source platform for building enterprise-grade agents. 强大易用的开源企业级智能体平台。项目地址: https://gitcode.com/GitHub_Trending/ma/MaxKB
把几十份产品手册丢进一个知识库,然后直接问"退货申请需要满足什么条件?",几秒后得到的不是搜索结果列表,而是一段带出处的答案——这就是 MaxKB 的日常用法。它定位为企业级智能体平台,核心价值是 RAG(检索增强生成,即"先查资料再让大模型照着答")问答、可视化工作流编排,以及对接数十家大模型厂商的模型管理。下面不聊宣传语,直接拆开看:它用什么技术组合解决了什么问题,一次提问的数据在内部是怎么流动的。
技术选型:每个组件都在解决一个具体问题
MaxKB 的选型不是堆新,而是每个问题都有对应解法,全部可以从 pyproject.toml 和 ui/package.json 核对:
- 向量检索不想引入独立向量数据库→ PostgreSQL + pgvector 扩展(installer/init.sql 里只有一句
CREATE EXTENSION "vector"),业务数据和向量同库,免去跨库一致性问题; - 对话链路是多步骤串联(问题改写→检索→生成)→ Django 5.2.16 + DRF 3.17.2 承载 API,流程本身用 chat_pipeline 的"步骤器"实现,每步一个抽象接口加一个默认实现;
- 文档解析、向量化耗时且可能中断→ Celery 5.5.3 + Redis,配合
celery-once防重复任务; - 模型厂商 API 差异巨大→ 统一走 LangChain 1.3.10 / LangGraph 1.2.6 的抽象,外加自己一层 Provider 封装(详见下文);
- 工作流画布需要拖拽式节点编辑→ 前端 Vue 3.5.13 + LogicFlow 1.2.27(流程图引擎)+ Element Plus 2.13.5,构建用 Vite 6.2.4。
一次提问的完整数据流
跟着一句话从前端走到答案回来。用户在应用页提问后,请求命中 chat_api.py 中的ChatAPI,随后进入 pipeline_manage.py 定义的流水线,四个步骤依次执行,代码都在 chat_pipeline/step:
- reset_problem_step:清理问题上下文;
- generate_human_message_step:调用 LLM 把用户口语化的问题补全成检索友好的文本(比如把"这个咋弄"补成"如何配置知识库相似度阈值");
- search_dataset_step:拿补全后的文本去 pg_vector.py 的
query()做混合检索,返回段落列表paragraph_list; - chat_step:把"问题 + 检索段落"组装成提示词,通过 LangChain 流式调用 LLM,逐 token 经 SSE 推回前端。
检索这一步最值得注意:它不是简单的向量近邻。以混合检索为例,blend_search.sql 先用余弦距离<=>取出候选,再叠加 PostgreSQL 全文检索的ts_rank_cd关键词分数:
-- 综合得分 = 向量相似度 + 关键词命中排名(归一化标志位32) (1 - vc.distance + COALESCE(ts_rank_cd(e.search_vector, plainto_tsquery('simple', %s), 32), 0)) AS comprehensive_score候选规模被LEAST(top_n * 10, 500)硬性封顶,防止 top_n 调大时全表扫描。写入侧同样埋了细节:ts_vecto_util.py 会把知识库级术语表(Termbase)的自定义词注入 tsvector 分词,解决"内部黑话检索不到"的问题。
三个有辨识度的关键设计
混合检索 + 按知识库切分的 HNSW 索引
pg_vector.py里有一段很"实战"的注释:当查询命中单个知识库时,用knowledge_id = 'xxx'而不是knowledge_id__in条件,因为后者用不上 PostgreSQL 的部分 HNSW 索引(per-KB partial HNSW indexes)。换言之,索引是"每个知识库一个",查询必须精确到单个库才能走索引——多库场景就逐库查询再合并排序(all_results.sort(...)那段)。这是用查询路径上的几次额外循环,换索引体积和构建速度的工程取舍。检索模式做成策略数组search_handle_list = [EmbeddingSearch, KeywordsSearch, BlendSearch],前端传search_mode即切换,新增模式只需实现ISearch两个方法。
多模型抽象层:20+ 厂商收敛成一个接口
base_model_provider.py 定义了骨架:IModelProvider(厂商)→ModelInfoManage(模型清单)→ModelInfo(模型名 + 鉴权凭证类 + 模型实现类)。impl/ 目录下有 20 多个厂商实现(OpenAI、Anthropic、DeepSeek、智谱、Ollama、火山引擎等),而ModelTypeConst把能力切成 9 种:LLM、EMBEDDING、STT、TTS、IMAGE、TTI(文生图)、RERANKER(重排)、TTV/ITV(视频)。业务代码只调get_model(model_type, model_name, credential),具体是哪家厂商、哪个 SDK 完全被屏蔽。凭证敏感字段由BaseModelCredential.encryption_dict加密入库,返回前端时脱敏为123******890样式。
工作流引擎:节点定义即 JSON
应用不只是固定流水线,还能变成图。默认工作流见 default_workflow.json——每个节点带type(如search-dataset-node)和properties.config.fields输入输出声明;step_node/ 下有 146 个节点实现,覆盖 LLM、条件分支、代码执行、知识库检索等。外部工具则通过 MCP(Model Context Protocol,让模型调用外部工具的标准协议,依赖mcp==1.28.1+langchain-mcp-adapters==0.3.0)接入,且工具执行被放进独立沙箱:common/mcp/sandbox.py 与 installer/sandbox.c 配合,代码类工具在隔离进程里跑,避免一个恶意工具打穿整个服务。
工程化:部署、权限与异步流水线
部署侧提供两套入口:start-maxkb.sh 本地脚本或 Dockerfile 容器化,Web 进程由 gunicorn 23.0.0 拉起,django-db-connection-pool==1.2.6解决 gunicorn 多 worker 下连接泄漏,django-redis==6.0.0承担会话与模型实例缓存(MaxKBBaseModel.is_cache_model()允许模型对象跨请求复用)。
文档处理是典型的异步流水线:上传后由 knowledge/task 下的 Celery 任务接手——pypdf 6.16.1 解 PDF、python-docx 解 Word、beautifulsoup4+jieba 0.42.1 清洗切词,分块结果批量bulk_create写入 Embedding 表;_batch_save每轮调用is_the_task_interrupted()检查任务是否被用户取消,取消即停,不浪费算力。
权限上走"工作空间 + 资源映射"模型:system_manage/sql/ 里的get_user_resource_permission.sql等查询决定用户能看到哪些知识库/应用/模型,外部调用则靠 application_api_key.py 的 API Key(支持过期时间,见迁移0007)做入口鉴权。
带得走的三点
- 向量库不一定要"专业":pgvector + 余弦距离 + 封顶候选数(
LEAST(top_n*10, 500))+ 按库切分 HNSW,在单库规模内完全够用,还省掉一套独立组件——代价是查询条件必须精确到分区键,这个取舍值得在自己的索引设计里权衡。 - 混合检索的融合公式可以直接抄:
1 - 余弦距离 + ts_rank_cd(归一化)的线性叠加比"向量/关键词二选一"鲁棒得多,尤其适合术语密集的内部文档。 - 模型层用"厂商→清单→实例"三级抽象,把 SDK 差异关在
impl/目录里,新增厂商不动业务代码;再配 MCP 沙箱执行外部工具,是"让模型安全地动手"的实用范式。若你基于 MaxKB 二次开发,扩展方向也很清晰:自定义ISearch接入重排模型、在 step_node 加领域节点、或把 Celery 换成本地任务队列做单机化部署。
【免费下载链接】MaxKB🔥 MaxKB is an open-source platform for building enterprise-grade agents. 强大易用的开源企业级智能体平台。项目地址: https://gitcode.com/GitHub_Trending/ma/MaxKB
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考