MaxKB 企业级智能体平台技术全景
- [一、产品定位与完整功能体系:从 RAG 问答到自动化智能体](#一、产品定位与完整功能体系:从 RAG 问答到自动化智能体)
-
- [1.1 MaxKB 解决的是 AI 应用交付问题](#1.1 MaxKB 解决的是 AI 应用交付问题)
- [1.2 从官方导航看完整功能地图](#1.2 从官方导航看完整功能地图)
- 二、系统架构与模块协作:一次入库和一次问答如何流转
-
- [2.1 技术分层与源码目录](#2.1 技术分层与源码目录)
- [2.2 文档入库链路:从原始文件到可检索向量](#2.2 文档入库链路:从原始文件到可检索向量)
- [2.3 在线问答链路:发布版本驱动执行](#2.3 在线问答链路:发布版本驱动执行)
- [2.4 工具与触发链路:让智能体主动连接业务](#2.4 工具与触发链路:让智能体主动连接业务)
- 三、核心实现链路:文档处理、RAG、工作流、模型与工具
-
- [3.1 文档解析、分段与知识维护](#3.1 文档解析、分段与知识维护)
- [3.2 RAG:从召回候选到生成答案](#3.2 RAG:从召回候选到生成答案)
- [3.3 简易智能体、工作流执行与会话/长期记忆](#3.3 简易智能体、工作流执行与会话/长期记忆)
- [3.4 模型适配与工具生态:统一接口,不掩盖能力差异](#3.4 模型适配与工具生态:统一接口,不掩盖能力差异)
- [3.5 Celery、PostgreSQL/pgvector 与 Redis](#3.5 Celery、PostgreSQL/pgvector 与 Redis)
- [四、Docker 部署与快速使用:完成第一个可评测智能体](#四、Docker 部署与快速使用:完成第一个可评测智能体)
-
- [4.1 使用当前 v2 README 命令启动](#4.1 使用当前 v2 README 命令启动)
- [4.2 按"模型---知识库---智能体---评测"快速上手](#4.2 按“模型—知识库—智能体—评测”快速上手)
- [4.3 生产环境使用离线安装和可恢复升级](#4.3 生产环境使用离线安装和可恢复升级)
- 五、发布集成与生产工程:从能演示到可运营
-
- [5.1 公开链接、嵌入和 OpenAI 兼容 API](#5.1 公开链接、嵌入和 OpenAI 兼容 API)
- [5.2 用证据和指标运营 RAG](#5.2 用证据和指标运营 RAG)
- [5.3 身份、资源权限与凭据边界](#5.3 身份、资源权限与凭据边界)
- [5.4 并发、后台任务与容量边界](#5.4 并发、后台任务与容量边界)
- [5.5 生产治理、问题定位与许可](#5.5 生产治理、问题定位与许可)
- 六、适用场景与总结:循序渐进地落地,而不是一次堆满功能
- 参考资料
MaxKB(Max Knowledge Brain)定位为"强大易用的企业级智能体平台"。它不是单一的聊天UI,也不只是向量数据库的管理页面,而是把模型接入、知识生产、检索生成、流程编排、工具调用、自动触发和应用发布组织成一条可持续运营的 AI应用交付链路,覆盖多模型管理、文档知识库、RAG 检索、可视化工作流、MCP/Skills/工具、自动触发、Web 嵌入与 API 集成。。团队可以先用简易智能体快速完成知识问答,再通过高级工作流加入多路召回、条件分支、多模态处理、MCP或业务工具,最后以公开链接、Web 嵌入或 API 接入现有系统。
GitHub仓库:https://github.com/cmyk-labs/MaxKB.git(如果这个仓库对你有帮助,欢迎在 GitHub 上点一个 Star ⭐ 支持一下。)
官方GitHub仓库:https://github.com/1Panel-dev/MaxKB
一、产品定位与完整功能体系:从 RAG 问答到自动化智能体
1.1 MaxKB 解决的是 AI 应用交付问题
直接调用一次大模型 API,只能证明"模型可以生成文本"。真正的企业知识助手还要解决资料持续更新、文档解析与分段、检索质量、回答边界、模型切换、流程控制、工具权限、发布集成、成本以及运维。MaxKB 将这些工作组织为一条渐进式路线:
text
模型可用
→ 文档可以解析、分段和检索
→ 简易 RAG 智能体可调试、可发布
→ 高级工作流可编排、可回滚
→ 工具/MCP/Skills/子智能体可调用
→ 定时或事件触发可自动执行
→ Web/API/第三方渠道可交付
→ 评测、日志、备份和权限可持续运营
这条路线也解释了 MaxKB 的"开箱即用,伴随成长"思路:业务尚不复杂时,不必先搭建庞大的工作流;需求增长后,再把知识检索、判断、工具和自动化逐步加入同一个平台。
图片来源:MaxKB v2 官方产品介绍。

这张产品理念图体现的是一条渐进路径:先用 RAG 解决"基于企业资料可靠回答",再用 Workflow 解决"按业务规则组织多个步骤",最后通过 Agent 让模型根据上下文选择知识、工具和其他能力。三者不是互相替代,而是由确定性到自主性的逐级组合。
1.2 从官方导航看完整功能地图
MaxKB v2 的主要模块不是相互孤立的功能页,而是一组彼此引用的资源。下面按"管理对象---核心能力---下游用途"梳理其功能体系。
| 功能域 | 核心能力 | 与其他模块的关系 |
|---|---|---|
| 首页 | 工作空间资源概览、运营监控趋势、资源使用排行 | 观察智能体、知识库、工具和模型的总体使用情况 |
| 模型 | 管理 LLM、Embedding、Reranker、语音、视觉、图片/视频生成等模型 | 知识库引用向量模型;智能体和工作流引用生成及多模态模型 |
| 知识库 | 通用文件、Web 站点、工作流知识库;解析、分段、向量化、同步、标签、命中测试、导入导出 | 为简易/高级智能体提供可检索知识;工作流知识库还可引用自定义数据源 |
| 智能体 | 简易智能体、高级工作流、模板中心、调试、发布历史、导入导出、关联资源 | 组合模型、知识库、工具、MCP、Skills 和其他智能体,形成最终 AI 应用 |
| 工具 | Python 自定义工具、工具工作流、Skills、MCP、数据源、工具商店 | 可被 AI 对话节点自主调用,也可作为显式工作流节点;数据源可服务知识库工作流 |
| 触发器 | 定时触发、Webhook 事件触发、启停和执行记录 | 无需人工对话即可定时或由外部事件启动智能体/工具 |
| 发布与接入 | 公开链接、全屏/移动端/浮窗嵌入、API Key、OpenAI 兼容调用 | 把完成的智能体交付给用户或业务系统 |
| 平台治理 | 用户、资源授权、系统设置、自定义语言等;X-Pack 还扩展工作空间、角色、共享资源、登录认证等 | 管理资源可见范围、团队协作及企业级接入边界 |
图片来源:MaxKB v2 官方快速入门。

当前主界面将首页、智能体、知识库、工具和模型作为核心入口。首页偏向资源与运营概览,其余四个模块分别对应"应用交付、知识供给、能力扩展、模型底座"。触发器、用户和系统设置则承担自动执行与治理职责。
模型层也不是只有"聊天模型"。官方模型文档将能力分为大语言、向量、重排、语音识别、语音合成、视觉、图片生成、文生视频和图生视频等类型。不同供应商支持的类型不同,因此选型应先看业务所需能力,再看具体供应商,而不是用一个 API Key 解决所有模型角色。
知识库层则覆盖从创建到维护的完整周期:通用知识库管理离线文档,Web 站点知识库同步在线静态文本,工作流知识库允许自主编排数据源、解析、分段和写入。文档进入知识库后还可以同步、重新向量化、生成问题、打标签、迁移、导出、替换原文档、启停以及手工维护分段。飞书知识库、共享资源等能力属于特定版本功能,不能把其他版本截图当成社区版承诺。
智能体层兼顾两种复杂度:简易智能体集中配置模型、提示词、历史记录、知识库、长期记忆和技能;高级智能体把 AI 能力、知识检索、业务逻辑、数据处理、工具和子智能体放到可视化画布中。模板中心进一步提供可复用的典型场景起点,减少重复搭建。
图片来源:MaxKB 官方 GitHub README 固定提交。
|---------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
|
工作流编排与实时对话调试 |
多供应商、多类型模型统一管理 |
|
文档分段查看与维护 |
问答、知识来源与执行信息 |
这组界面展示了 MaxKB 的关键闭环:模型页提供基础能力,知识库把资料变为可检索分段,工作流将检索和模型组合成业务逻辑,问答页再把答案、知识来源与执行信息交给最终用户。
二、系统架构与模块协作:一次入库和一次问答如何流转
2.1 技术分层与源码目录
官方系统架构和仓库依赖表明,MaxKB 使用 Vue/LogicFlow 构建前端与流程画布,后端基于 Python、Django 和 LangChain,数据与向量检索使用 PostgreSQL/pgvector,运行配置中还使用 Redis;源码同时引入 Celery 等任务组件来处理文档加工等长任务。
图片来源:MaxKB v2 官方系统架构。

阅读这张架构图时要注意两点:第一,图中的工作空间、共享资源和部分统一治理能力涉及 X-Pack,不能据此推断社区版拥有完全相同的权限体系;第二,架构图中仍可能出现旧术语"应用",当前 v2 界面和文档主要称为"智能体"。下文统一使用"智能体"。
| 层次 | 主要实现 | 关键职责 |
|---|---|---|
| 交互层 | Vue 3、TypeScript、Vite、Element Plus、LogicFlow | 管理页面、工作流画布、调试面板、公开问答与嵌入界面 |
| API 与领域层 | Django、Django REST Framework | 用户/资源、知识库、智能体版本、对话、工具与系统接口 |
| AI 编排层 | LangChain、模型供应商适配器、MCP/Skills 相关依赖 | 统一模型消息、RAG 上下文组装、节点执行和工具调用 |
| 异步任务层 | Celery、调度与互斥组件 | 向量化、分词、问题生成、Web 同步、长期记忆等耗时或后台工作 |
| 数据层 | PostgreSQL、pgvector、Redis | 业务对象、对话与配置持久化,向量相似度检索,缓存和运行协同 |
| 交付层 | Dockerfile、安装器、启动脚本、main.py |
构建前后端、初始化依赖、启动 Web/任务/本地模型相关服务 |
核心目录与业务域基本一一对应:
text
MaxKB/
├── apps/
│ ├── application/ # 智能体、版本、工作流配置和运行逻辑
│ ├── chat/ # 对话、嵌入、流式输出与对外对话接口
│ ├── knowledge/ # 知识库、文档、分段、向量化任务和检索
│ ├── models_provider/ # 供应商、凭据、模型类型与调用适配
│ ├── tools/ # 自定义工具、工作流工具、MCP、Skills、数据源
│ ├── common/ # 认证、加密、工具沙箱与跨领域公共能力
│ ├── system_manage/ # 系统参数、许可证和平台级管理逻辑
│ ├── trigger/ # 定时与事件触发
│ ├── folders/ # 资源文件夹组织
│ ├── users/ # 用户相关逻辑
│ └── maxkb/ # Django 配置、URL 和项目级入口
├── ui/ # Vue 前端
├── installer/ # 容器构建和启动脚本
├── apps/manage.py # Django 管理命令入口
├── main.py # 初始化、迁移与服务启动入口
├── pyproject.toml # Python 依赖与工程配置
└── LICENSE # GPL-3.0
这种按领域拆分的意义在于:模型供应商变化不会迫使知识库重写;知识库处理可以独立于问答请求异步运行;智能体只保存资源引用和流程配置,发布端按版本执行;工具和触发器可以被多个智能体复用。
2.2 文档入库链路:从原始文件到可检索向量
文档入库不是单次数据库插入,也不是"上传后由 Celery 包办解析、清洗、分段和向量化"。通用文件入库在源码中分成两个阶段:解析预览、业务对象写入主要位于同步请求链;Embedding、全文检索字段生成和索引维护再交给后台任务。
text
浏览器上传文件
→ Document.Split 接收文件和分段参数
→ 按格式选择 HTML / DOCX / PDF / Excel / CSV / ZIP / Text Handler
→ 转换为 Markdown 或结构化文本
→ SplitModel 生成分段预览
→ 用户确认后,在事务中写入 Document / Paragraph / Problem / 映射
→ post_embedding 触发 Celery embedding_by_document
→ Paragraph.chunks 与关联问题分别向量化
→ 写入 Embedding 和 PostgreSQL SearchVector
→ 创建按知识库过滤的 partial HNSW 索引
用户确认预览后,文档、段落、问题和映射在数据库事务中同步写入;事务完成后才提交 embedding_by_document。Celery 任务使用 QueueOnce 按资源去重,监听器还通过 Redis Lock 避免同一文档并发向量化。由此可见,后台任务隔离的是 Embedding、分词、问题生成和 Web 同步等耗时工作,不能把通用文件解析也笼统算进 Celery。
工作流知识库把这条管线进一步显式化:数据源节点负责获取内容,文档解析节点提取文本,分段节点按规则生成可检索单元,知识库写入节点完成持久化和向量化。适配特殊数据格式时,可将自定义数据源接入这条链,而不必修改通用上传流程。
2.3 在线问答链路:发布版本驱动执行
正式问答由最新已发布版本驱动,调试请求则读取当前编辑态配置;无论哪一种入口,简易智能体和高级智能体都不共享同一种外层执行模型:
text
简易智能体
用户问题
→ 可选问题优化
→ 固定的知识库检索
→ 组装历史、知识与提示词
→ 模型直答或 DeepAgent 工具循环
→ 保存 ChatRecord
高级智能体
用户问题
→ WorkflowManage 从 start-node 开始
→ 按边、条件和依赖调度节点
→ 节点/全局/会话变量传值
→ 知识检索、AI、工具、循环等节点协作
→ 汇总结果并保存执行详情
简易智能体按固定步骤执行 RAG,不由 LLM 自主决定是否检索;只有最后的对话步骤绑定了工具、MCP、Skills 或子智能体时,才会进入自主工具调用。高级智能体则是确定性的工作流 DAG,其中某个 AI 对话节点也可以局部开启 Agent。更准确地说,外层流程限制执行边界,局部模型获得自主性;不能把高级智能体理解成由 LLM 自动规划一切。
"编辑态"和"发布态"分离仍是生产稳定性的关键。画布自动保存或调试成功,不代表正式问答已经切换;只有发布成功后,新版本才进入生产链路。节点输出通过变量传给后置节点,分支、汇集、异常和中断语义共同决定后续执行路径。
2.4 工具与触发链路:让智能体主动连接业务
工具模块提供 Python 工具、可复用工具工作流、Skills、MCP、数据源和工具商店。启用后,它们既可以作为高级工作流中的显式组件,也可以交给支持函数调用的 LLM 按对话上下文选择。触发器再把"用户提问才执行"扩展为两种自动化入口:定时触发按周期/Cron 执行,事件触发通过带 Bearer Token 的 Webhook 启动智能体或工具。
因此 MaxKB 的资源关系可以理解为:
text
模型 ─┬─> 知识库向量化
└─> 智能体 AI/多模态节点
知识库 ───────────────> 智能体检索节点
工具/MCP/Skills ──────> 智能体或工具工作流
智能体 ───────────────> 公开链接 / 嵌入 / API
触发器 ───────────────> 智能体或工具自动执行
这也说明了为什么平台提供"查看关联资源":删除或更换一个模型、知识库或工具前,应先看哪些下游资源依赖它,而不是仅凭资源名称判断影响范围。
三、核心实现链路:文档处理、RAG、工作流、模型与工具
3.1 文档解析、分段与知识维护
MaxKB v2 的通用知识库支持 TXT、Markdown、PDF、DOCX、HTML、XLS、XLSX、CSV、ZIP 等格式,但解析器不是简单读取全部文字。不同 Handler 先把文档归一为统一结构,再交给 SplitModel 处理标题树和正文。
解析入口还会先保存源文件并返回 source_file_id。文件模型按 SHA-256 识别相同内容,复用对应的 PostgreSQL Large Object,并采用压缩、分块方式写入。解析文本服务检索,原文件则服务下载、替换和证据追溯;两条数据线通过 source_file_id 关联。
SplitModel 的关键步骤可以概括为:
text
统一 CRLF/CR 换行并移除空字符
→ 暂时屏蔽 fenced code block 内部内容
→ 按 Markdown 标题或自定义正则递归构造标题树
→ 将父标题链合并为分段 title
→ 无标题或正文超长时按句界和长度继续切分
→ 可选执行基础字符清洗
屏蔽代码块是一个容易忽略但很实用的细节:如果直接用 # 判断 Markdown 标题,代码示例中的注释可能被误认为章节。对于没有标题的长文本,smart_split_paragraph() 会在长度上限前半区以后反向寻找句号、问号或感叹号,找不到合适句界才硬切,而不是调用 LLM 判断语义边界。
这里还存在一处需要按版本理解的文档差异:当前 MaxKB v2 官方知识库文档将智能分段描述为"在分段长度以内查找回车进行截取",而本文固定提交的 smart_split_paragraph() 实际在长度上限的后半区反向查找句号、问号和感叹号,找不到才按长度硬切。前者是当前产品文档的公开说明,后者是提交 f9deee82d5a00ab7858b9a2f7a05a2ed5749bb62 的代码行为;调试具体版本时应以实际部署源码和分段预览为准。
三种界面入口的真实关系如下:
| 入口 | 传给后端的内容 | 源码中的实现 |
|---|---|---|
| 智能分段 | 使用格式默认规则 | 默认标题正则、标题树和长度切分 |
| 高级分段 | patterns、limit、with_filter |
仍由同一个 SplitModel 执行,只替换规则、长度和清洗开关 |
| QA 导入 | CSV/XLS/XLSX/ZIP 中的标题、答案、问题列 | 不走普通标题切分;问题通过映射表关联答案段落 |
所以"高级"不是换用另一个语义模型,"QA"也不是第三种同类分段算法。基础清洗只处理换行、空格、# 和制表符等字符;复杂页眉页脚、错乱表格和扫描 PDF 应先改进源文件,或通过知识库工作流加入专用处理能力。
从数据结构看,知识不是只保存为一个字符串。Document 管理文件,Paragraph 保存用户可见的完整证据段落,Problem 保存常见问法,ProblemParagraphMapping 建立问题与答案段落的多对多关系,Paragraph.chunks 则保存更小的向量块。向量化阶段同时处理正文 Chunk 和关联问题,因此可能通过用户问法命中某个标准答案,也可能通过正文语义命中同一段落。
python
# 代码含义的简化表达,字段名对应实际模型
paragraph.chunks = text_to_chunk(paragraph.content)
for chunk in paragraph.chunks:
embed(chunk) # 正文小块
for problem in paragraph.problem_list:
embed(problem.content) # 常见问法,最终指回 paragraph_id
默认小块约为 256 字符并优先在标点、空格或换行附近断开。它能降低长段落的语义稀释,却也可能拆散合同条件、表格行和操作步骤。因此不能只调界面上的 Paragraph 长度,还要检查最终 Chunk 是否仍保留业务含义。
业务对象写入后,Celery 才异步完成 Embedding。PGVector._batch_save() 在一批处理中写入向量和 PostgreSQL SearchVector;术语表还会作为 jieba 用户词参与全文检索分词。向量维度小于 2000 时,create_knowledge_index() 会为知识库创建带 WHERE knowledge_id = ... 条件的 partial HNSW 索引。
知识库维护也不仅是重新上传。MaxKB 支持 Web 文档同步、重新向量化、生成问题、标签管理、分段增删改、文档迁移、导出和替换原文件。调优时应优先检查四件事:可见段落是否完整表达证据、向量小块是否拆散条件、关联问题是否接近真实问法、Embedding 维度和模型是否与现有知识库一致。平均分段长度只是表象,最终标准仍是"真实问题能否稳定命中正确且完整的证据"。
3.2 RAG:从召回候选到生成答案
图片来源:MaxKB v2 官方产品介绍。

官方 RAG 原理图把知识准备与在线问答连接起来:文档侧经过解析、分段和向量化形成可检索知识;问题侧检索相关片段,并把片段与用户问题共同送入大模型。这样做不是让模型"记住"企业文件,而是在每次回答前动态提供证据上下文。
向量模型将问题编码为向量 q q q,知识分段已有向量 d d d。常见余弦相似度为:
c o s i n e ( q , d ) = q ⋅ d ∥ q ∥ ∥ d ∥ \mathrm{cosine}(q,d)=\frac{q\cdot d}{\lVert q\rVert\lVert d\rVert} cosine(q,d)=∥q∥∥d∥q⋅d
MaxKB 的 RAG 不是固定的"向量召回 + 全文召回 + 自动 Rerank"。真实链路是从三种初检模式中选择一种,Reranker 仅在高级工作流显式接入对应节点时执行:
text
原始问题
→ 根据当前执行入口收缩可访问的知识库范围
→ 校验多个知识库使用相同的 Embedding 模型
→ 可选问题优化并生成问题向量
→ 按知识库分别选择一种初检
├─ embedding:向量距离
├─ keywords:PostgreSQL 全文检索
└─ blend:向量候选内叠加全文得分
→ 多知识库结果全局排序并恢复完整 Paragraph
→ 初检相似度阈值与 Top N 过滤
→ 可选显式 Reranker 节点
→ 按检索节点或 Reranker 节点的字符上限生成最终上下文
→ 将证据注入提示词
→ LLM 生成答案
→ 返回答案、知识来源和执行详情
权限过滤发生在访问向量表之前,而不是先跨空间召回再从界面隐藏。高级知识检索节点会显式处理工作空间、共享资源和聊天用户授权;简易链路在聊天用户场景下通过授权处理器收缩知识库范围。多知识库还必须使用相同的 Embedding 模型,因为不同维度或不同向量空间中的数值不能直接比较;更换 Embedding 后应重新向量化和重新做命中测试。
三种检索模式在 PGVector 中对应三套 SQL:
| 模式 | 核心实现 | 适合的数据 |
|---|---|---|
embedding |
pgvector 余弦距离,以 1 - distance 计分 |
同义改写、自然语言语义匹配 |
keywords |
websearch_to_tsquery('simple')、@@、ts_rank_cd |
型号、编号、术语和精确词语 |
blend |
先取向量候选,再在候选内增加全文分数 | 语义匹配为主,同时用关键词调整排序 |
向量检索会先取 min(top_n × 10, 500) 个向量候选,再按 paragraph_id 去重、过滤阈值和截取 Top N。候选池需要放大,是因为一个段落可能对应多个正文 Chunk 和多个关联问题;如果只取 Top N 条向量,去重后可能剩不下足够的段落。
混合检索最值得详细说明。源码中的综合分数为:
sql
comprehensive_score =
(1 - vector_distance)
+ COALESCE(
ts_rank_cd(search_vector, websearch_to_tsquery('simple', query), 32),
0
)
全文得分只作用在 vector_top 候选内部。因此它不是"向量和全文两路独立召回后合并",纯关键词结果如果没有进入向量候选池,也不会被重新带回。三种模式的分数尺度不同,切换模式后不能机械复用同一个阈值。
向量维度低于 2000 时,每个知识库可拥有自己的 partial HNSW 索引。多知识库检索会逐库执行,以便命中对应索引,再在应用层合并和排序。这种实现缩小了单次索引范围,但知识库数量上升时查询次数也会增长;把大量碎片化知识库无限挂到同一智能体上,并不一定优于先做好知识治理。
初检返回的是 paragraph_id,应用层再加载完整段落、知识库名、文档名和元数据。若文档配置了 directly_return 且得分达到专用阈值,简易智能体可直接返回得分最高的原始段落,适合标准话术、图片和链接;普通 optimization 模式才把证据交给 LLM 生成。
Reranker 位于 独立工作流节点。节点将候选转换为 LangChain Document,调用所选重排模型的 compress_documents(),再根据 relevance_score、Top N、阈值和最大字符数裁剪。它只会重新排列已有候选,无法找回初检阶段已经丢失的正确段落。
高级知识检索节点本身会输出完整 paragraph_list,同时生成受 max_paragraph_char_number 限制的文本字段;连接 Reranker 时可以把完整候选列表交给重排节点,Reranker 再应用自己的一套 relevance_score、Top N 和最大字符数限制。因此"检索节点裁剪"和"重排节点裁剪"是两组参数,不应合并理解。
调优顺序应当是:
- 先确认源文档和 Paragraph 保存了完整事实;
- 检查 256 字符 Chunk 与关联问题能否把正确段落带入候选;
- 分别标定向量、全文或混合模式的阈值和 Top N;
- 确认正确证据已进入初检后,再评估 Reranker 是否能提升位置;
- 最后检查最大引用字符数和 Prompt 是否截断或忽略证据。
Top N 太小会在重排前丢失跨段答案,太大则增加噪声、重排成本和上下文开销;相似度阈值过高会造成"有资料却无命中",过低会引入边缘片段;最大引用字符数按字符而非精确 Token 裁剪,可能截断条件、单位或结论。应同时记录"正确段落是否进入初检""重排后位次""实际送入 LLM 的文本",否则只看最终答案很难定位问题。
无命中时的处理更重要。对制度、合同条款、产品参数等事实型场景,应优先配置明确拒答或指定回复;让 LLM 在无资料时继续自由回答,会重新引入 RAG 本应降低的幻觉风险。
排障时可按证据链区分问题:
| 现象 | 证据检查 | 优先改进 |
|---|---|---|
| 知识库没有可靠答案 | 源资料、版本、同步时间 | 补齐资料,删除过期或冲突内容 |
| 解析后内容残缺 | 文档预览、表格、标题、PDF 文本层 | 更换源格式,预先 OCR 扫描件,或自定义解析链 |
| 正确片段未进入候选 | 命中测试、分段、检索模式 | 调整分段、Embedding、初检模式、阈值和 Top K |
| 候选有正确片段但排序靠后 | 初召回与重排结果 | 引入/调整 Reranker,优化关联问题与标签 |
| 正确片段已送入 LLM 但回答偏离 | 执行详情、提示词、上下文 | 收紧知识边界、输出格式和拒答规则,核对截断 |
3.3 简易智能体、工作流执行与会话/长期记忆
MaxKB v2 将智能体分为"简易"和"高级",但这不是同一套 Agent 加上不同数量的配置项。源码里存在两种外层执行模型:简易智能体使用固定 Pipeline,高级智能体使用可配置 DAG;只有当 AI 对话步骤绑定了工具时,局部执行才进入由模型自主选择工具的 Agent 循环。
简易智能体按固定步骤执行 RAG。 ChatSerializers.chat() 识别到 SIMPLE 类型后,通过 PipelineManage 组装步骤:
text
用户问题
→ 可选 BaseResetProblemStep:结合历史优化问题
→ BaseSearchDatasetStep:检索已绑定知识库
→ BaseGenerateHumanMessageStep:组装历史、知识与提示词
→ BaseChatStep:模型回答或 DeepAgent 工具循环
→ 保存 ChatRecord 并输出
问题优化、检索和上下文组装都有固定位置,LLM 不会自行决定是否跳过知识库。命中"直接回答"段落,或无命中且配置了指定回复时,Pipeline 还可以短路,不必调用生成模型。最后的 BaseChatStep 才判断能力集合:没有工具时直接调用 chat_model.stream() 或 invoke();绑定了 Tool、MCP、Skills 或子智能体时,才转入 DeepAgent。也就是说,简易模式先按固定步骤完成问题优化、知识检索和上下文组装;仅在绑定这些能力时,最后的模型步骤才进入自主工具调用循环。
高级智能体:工作流 DAG。 正式问答读取已发布版本中的 work_flow JSON,调试请求使用当前编辑态配置,之后都由 WorkflowManage 从开始节点调度:
text
chat_work_flow
→ Workflow.new_instance
→ WorkflowManage.run
→ 执行当前节点
→ 根据边、branch_id 和依赖寻找后继节点
→ 写入节点上下文、全局变量和会话变量
→ 汇合结果并由 PostHandler 持久化
工作流中的节点包括:
| 组件组 | 代表节点 |
|---|---|
| AI 能力 | AI 对话、意图识别、问题优化、文本转语音、语音转文本、图片生成/理解、视频生成/理解 |
| 知识库 | 知识库检索、文档标签检索、多路召回 |
| 业务逻辑 | 判断器、表单收集、指定回复、循环 |
| 数据处理 | 变量赋值、变量聚合、变量拆分、参数提取 |
| 扩展能力 | MCP 调用、文档内容提取、自定义工具、工具工作流、其他智能体 |
一个节点出现多个可执行后继分支时,会提交给进程内全局 ThreadPoolExecutor(max_workers=200);条件节点通过 branch_id 选择出边,汇合节点等待依赖,节点还能配置异常分支、中断和最终输出。这里的 200 是线程池配置,不是平台吞吐承诺。
节点间不是拼接一段不断膨胀的总 Prompt,而是通过三类状态协作:节点上下文保存输入、输出、Token、耗时和错误;全局变量贯穿本次执行;会话变量保存在 Chat.meta,可供同一 chat_id 的后续轮次使用。连线的后置节点通过 {``{节点名称.变量名称}} 引用前置输出。画布中不能留下流程外孤立节点,同一工作流节点名称不能重复;重命名后要重新检查变量引用。
多模态节点必须与实际模型能力匹配。例如开启视觉输入但选择纯文本模型会执行失败。工具调用同样依赖 LLM 的函数调用能力;模型不支持时,界面配置不会凭空补齐该能力。
图片来源:MaxKB 官方 GitHub README 固定提交。

工程上应把每个节点视为有明确输入、输出和失败语义的函数。权限校验、金额判断、数据库写入和审批等确定性步骤适合显式节点;难以提前枚举的语言理解和工具选择再交给 AI 节点。外层 DAG 固定业务边界,局部 Agent 保留自主性,既便于审计,也方便从执行详情定位失败节点。
短期历史:PostgreSQL 持久化,Redis 加速热会话。 Chat 保存会话和会话变量,ChatRecord 保存每轮问题、答案、Token、耗时、节点详情和知识来源;ChatInfo 则把当前运行所需状态缓存到 Redis 30 分钟。热缓存最多序列化最近 20 轮,缓存失效重新打开会话时从 PostgreSQL 恢复最近 5 轮,之后再根据 dialogue_number 截取上下文。因此"配置 20 轮"不等于冷恢复路径一定能重新载入 20 轮。
高级 AI 节点还有两种历史口径:WORKFLOW 使用每轮工作流最终问答,NODE 从执行详情中读取当前 AI 节点自己的历史。一个工作流同时存在分类、翻译和总结节点时,NODE 模式可以避免不同职责的消息互相污染。
长期记忆:每个智能体、每个用户一份文本画像。 ApplicationLongTermMemory 的唯一约束是:
text
unique(application, chat_user_id)
它跨同一用户在同一智能体下的多个 chat_id 共享,但不会跨智能体共享;字段中保存一份持续更新的 memory 文本,不是向量记忆库,也不是逐条事实对象。轮次模式在对话结束后由 Celery 异步任务判断并提取;定时模式由 APScheduler 按 daily、weekly、monthly、interval 或 cron 执行。两种模式都会把已有记忆与近期对话交给专用模型,按偏好、背景、约定和目标重新整理,然后覆盖原记录。
简易智能体采用显式占位符注入:
python
system_prompt = system_prompt.replace("{memory}", memory)
系统提示词没有 {memory} 时,记忆不会自动追加。高级智能体则在开始节点读取记忆,放入节点变量和全局变量 memory,后续节点决定是否引用。当前提交中,简易智能体的替换逻辑出现在流式路径,非流式路径没有看到完全等价的查询和替换,因此文章不能笼统承诺所有调用形态都自动注入长期记忆。
工具 Agent 创建时传入的 LangGraph MemorySaver 也不是产品长期记忆。它在每次 _yield_mcp_response() 中重新实例化,并仅作为该次 create_deep_agent() 调用的 checkpointer;MaxKB 没有将它持久化,也没有在下一轮请求中恢复。真正跨请求存在的是 PostgreSQL/Redis 中的对话历史,以及 ApplicationLongTermMemory。
3.4 模型适配与工具生态:统一接口,不掩盖能力差异
apps/models_provider 将上层的模型角色与具体供应商实现解耦。智能体只需知道要调用的是 LLM、Embedding、Reranker 或某种多模态模型;供应商适配层处理凭据、API 地址、基础模型名称、参数校验和 SDK 差异。LangChain 相关依赖提供统一的模型和消息抽象。
"模型中立"不等于不同模型完全可互换。替换模型时至少要重新验证:上下文长度、工具/函数调用、多模态输入、流式输出、Embedding 维度、Reranker 接口、速率限制、响应格式和价格。尤其不能在已有知识库中随意替换为维度不同的 Embedding 后继续使用旧向量;应按产品流程重新向量化并重新做命中测试。
MaxKB v2 的工具体系比"写一个函数"更完整,但要先回答一个架构问题:工具、MCP 和 Skills 是先经过语义路由,还是一次性交给 LLM?根据当前源码,答案是"创建者先绑定并校验权限,运行时过滤能够再次识别的资源,再把配置范围内的能力交给 DeepAgent",没有发现 MaxKB 在调用前执行向量检索或 Top-K 工具路由。
text
创建或编辑智能体时校验工具与子智能体的绑定权限
→ 运行时收集 mcp_tool_ids / tool_ids / skill_tool_ids / application_ids
→ 按工作空间及可识别的平台用户过滤 Tool / MCP / Skill ID
→ 检查子智能体发布状态与 Application API Key
→ 转换为 MCP Tool、StructuredTool 或 Skill 目录
→ 获取所选 MCP Server 暴露的函数
→ 将工具列表一次性传给 create_deep_agent
→ LLM 在 Agent 循环中选择调用
这里的"全量"有严格边界:不是把平台所有工具交给模型,而是把当前智能体或 AI 节点绑定后仍然有效的能力交给模型。Tool、MCP、Skill 在运行时会再次按工作空间和可识别的平台用户过滤;子智能体的资源权限主要在保存绑定关系时校验,执行时再检查发布状态和 API Key。公共聊天用户不会自动映射成工作空间平台用户。若一个被选中的 MCP Server 暴露多个函数,MultiServerMCPClient.get_tools() 会取得这些函数;MaxKB 没有再按当前问题做单函数裁剪。
不同资源的适配方式如下:
| 资源 | MaxKB 的转换方式 | 交给 Agent 的形态 |
|---|---|---|
| MCP | 读取所选 Server 配置,通过 MultiServerMCPClient 连接 |
Server 暴露的 MCP Tools |
| 自定义 Python 工具 | AST 提取公开顶层函数,生成本地 FastMCP stdio Server | MCP Tool |
| 工具工作流 | 读取发布版本,从 tool-base-node.user_input_field_list 生成 Pydantic Schema |
LangChain StructuredTool |
| 子智能体 | 使用内部 Application API Key 连接本机 /api/mcp |
Streamable HTTP MCP Tool |
| Skills | 解压 ZIP,挂载到本次 Agent 的 /skills |
Skill 目录,而非普通函数 Schema |
自定义 Python 工具的统一方式很有代表性。工具代码转换逻辑 解析 AST,找出名称不以下划线开头的顶层函数,为它们添加 @mcp.tool,再生成本地 FastMCP 服务。上层 Agent 因而不必区分"第三方 MCP 函数"和"平台内 Python 函数"。
工具工作流没有转成 MCP,而是由 get_tools() 读取最新发布版本,从工具基础节点 tool-base-node 的 user_input_field_list 构建输入 Schema,再用 StructuredTool.from_function() 包装。模型眼中它仍是一个名称、描述和参数明确的工具,调用后内部重新创建 ToolWorkflowManage 执行多步业务流程。
子智能体也作为工具提供给外层 Agent:外层不会把另一份 Prompt 直接拼入当前上下文,而是通过内部 API Key 调用本机 /api/mcp。子智能体仍在自己的发布版本、知识库和工作流边界中运行,外层只接收工具结果。这种通过本机回环地址调用 MCP 的方式,让智能体之间的调用复用了同一套工具协议。
Skills 的处理方式不同。绑定的 Skill 以 ZIP 文件保存,每次执行时解压到:
text
/tmp/<chat_id>/skills
初始化参数写入 Skill 顶级目录的 .env,随后创建 Agent:
python
agent = create_deep_agent(
model=chat_model,
tools=tools,
skills=["/skills"],
backend=SandboxShellBackend(root_dir=temp_dir, virtual_mode=True),
checkpointer=MemorySaver(),
)
也就是说,MCP、自定义工具和工具工作流进入 tools 列表,Skills 则作为目录挂载给 DeepAgents。MaxKB 负责选择、解压、初始化和清理,何时读取 Skill 说明或脚本由外部 deepagents 依赖负责;仅凭 MaxKB 仓库不能进一步断言它采用了某种内部向量路由算法。
创建 Agent 后,"模型请求工具---执行工具---把结果返回模型---继续推理"的循环由 DeepAgents/LangGraph 完成。MaxKB 负责聚合不同模型的流式 tool_call_chunks、渲染工具输入输出、保存可识别的执行记录,并通过递归上限阻止无限循环。核心创建过程可在 flow/tools.py 中看到。
高级工作流中的 MCP 节点和工具节点又是另一条路径:节点已经保存具体 Server、工具名和参数映射,运行时直接调用,不需要 LLM 选择。因此可以按风险选择三种方案:
- 开放式助手:AI 节点绑定一组工具,由模型自主选择;
- 可审计流程:意图识别或判断器先路由,再进入确定性的工具节点;
- 混合模式:外层 DAG 限定场景和权限,某个分支内只给 Agent 少量相关工具。
工具数量很多时,当前实现不会自动解决 Schema 占用上下文、描述相似和误调用问题。更稳妥的做法是按业务域拆分智能体或 AI 节点,减少单节点绑定工具数量,并为每个工具写清适用条件、参数约束、返回格式和副作用。
新建 Tool、Skills、MCP 和数据源默认禁用,调试后再启用只是第一道边界。模型输出仍应视为不可信调用建议:服务端需要保留绑定白名单和运行期权限检查;数据库使用只读或最小权限账号;HTTP 工具限制目标域、重试和超时;高风险写操作增加人工确认。MaxKB 还实现了两类用途不同的本地沙箱执行路径,不能只看 SandboxShellBackend 这一个类。
自定义 Python Tool 的执行沙箱。 工具节点、触发任务和知识库工具等确定性调用会进入 ToolExecutor.exec_code():启用沙箱后,子进程先切换到低权限 sandbox 用户,清空继承环境,再通过 LD_PRELOAD 加载项目编译的 sandbox.so。Linux 路径还会为直接执行设置地址空间上限、CPU 亲和性和超时;当前代码默认读取 256 MB 内存、1 个 CPU 核与 3600 秒超时配置,但这些只是保护参数,不是性能指标。AI 对话中绑定的 Python Tool 则由同一个 ToolExecutor 生成 FastMCP stdio Server,启动配置同样切换用户、清空环境并加载 sandbox.so,随后再作为 MCP Tool 交给 Agent。
Skills 的 Shell 沙箱。 create_deep_agent() 使用的 SandboxShellBackend 首先将模型看到的 /skills/... 虚拟路径映射到本次会话临时目录;启用沙箱后,它再把命令列表拆成简单命令,为每条命令增加 env -i、LD_PRELOAD=/opt/maxkb-app/sandbox/lib/sandbox.so 和 gosu sandbox 前缀。这样既避免 $()、反引号等先在父 Shell 中展开,也把 Skill 脚本执行限制在低权限用户和项目的动态库策略中。
官方一体化镜像不是默认关闭这套机制:installer/Dockerfile-base 已设置 MAXKB_SANDBOX=1,并配置受限主机与沙箱包路径;installer/sandbox.c 根据配置约束网络目标、动态库加载路径与方式、子进程、可执行内存映射和部分直接系统调用。直接运行源码或自行制作镜像时,如果没有等价地启用并准备 sandbox 用户、sandbox.so 和相关路径,上述操作系统级限制不会自动出现。
这仍然是同一 MaxKB 容器内的低权限用户、资源限制和 LD_PRELOAD 策略,不是为每次工具调用创建独立容器、虚拟机或远程执行环境。部署侧仍需使用只读挂载、最小网络、容器权限、CPU/内存限额、密钥隔离和审计共同收紧边界,不能因为类名含有 Sandbox 就承诺完全隔离。
触发器把这些能力变成自动化任务。定时触发适合日报、周期同步和巡检;Webhook 事件触发适合由业务系统在事件发生时启动智能体或工具。Webhook 的 URL 与 Bearer Token 应按 API 密钥保护,启用前验证调用方、参数和幂等性,并通过执行记录追踪输入、输出和失败原因。
3.5 Celery、PostgreSQL/pgvector 与 Redis
Celery 承担的是向量化、分词、关联问题生成、Web 站点同步、长期记忆提取和定时任务部署等后台工作;普通文件解析预览与文档/段落写入主要仍在同步请求链。前端根据状态展示等待、处理中、成功或失败,生产环境应同时监控任务积压、单任务耗时、模型错误和重复提交。
向量化、问题生成和同步任务大量使用 celery-once:以 knowledge_id、document_id 或 paragraph_id 等资源 ID 作为唯一键,阻止相同资源在锁有效期内重复排队。项目还实现了 RedisLock,通过 SET key uuid NX EX timeout 获取锁,释放时用 Lua 比较持有者 UUID 后再删除,避免误删后来者的锁。它适合去重和互斥,但获取失败通常直接跳过,且没有自动续租,不能理解为强一致分布式事务。
PostgreSQL 同时保存用户、模型、知识库、智能体、文档、分段、对话和全文检索字段,pgvector 扩展承载向量;Redis 则同时服务 Django Cache、Celery Broker/Backend 和部分互斥锁。一次 Embedding 写入会准备向量与 SearchVector;向量维度低于 2000 时使用按知识库过滤的 HNSW,全文字段使用 GIN。这种设计降低了外部组件数量,但也意味着数据库连接、索引体积、磁盘 IOPS 和 Vacuum 状态都会直接影响 RAG。
Celery App 虽然声明了 celery 与 model 队列,公开服务启动映射主要能确认默认 celery Worker,不能仅凭队列声明就声称已经完成双队列独立弹性伸缩。一体化镜像适合体验,数据规模或并发提高后仍应结合数据库连接池、Redis 连接、任务并发、外部模型限额、备份和恢复时间做容量规划,不能只增加 Web 进程。
四、Docker 部署与快速使用:完成第一个可评测智能体
4.1 使用当前 v2 README 命令启动
仓库 README 的一体化 Docker 方式适合开发验证和快速体验。Linux:
bash
docker run -d \
--name=maxkb \
--restart=always \
-p 8080:8080 \
-v ~/.maxkb:/opt/maxkb \
registry.fit2cloud.com/maxkb/maxkb
Windows Docker Desktop:
powershell
docker run -d --name=maxkb --restart=always -p 8080:8080 -v C:/maxkb:/opt/maxkb registry.fit2cloud.com/maxkb/maxkb
查看状态和最近日志:
bash
docker ps --filter name=maxkb
docker logs --tail 200 maxkb
容器健康后访问 http://服务器IP:8080。当前 README 给出的初始账号为:
text
用户名:admin
初始密码:MaxKB@123..
首次登录立即修改管理员密码。正式环境不要在没有 HTTPS、访问控制和防火墙策略时直接把 8080 暴露到公网。
卷参数 -v ~/.maxkb:/opt/maxkb 或 -v C:/maxkb:/opt/maxkb 决定数据实际落在哪个宿主机目录。重建或升级容器前,用 docker inspect maxkb 确认旧挂载并完成备份;新容器如果挂载一个新的空目录,会表现为一套空系统。
4.2 按"模型---知识库---智能体---评测"快速上手
第一步:准备模型。 至少添加一个 LLM 和一个 Embedding。LLM 负责理解与生成,Embedding 负责问题/分段向量化;Reranker 可稍后按效果增加。配置基础模型名、API 地址和凭据后,先做连通性校验。若连接公网模型,还要明确提示词、用户问题和检索片段是否允许发送给服务商。
第二步:创建小型测试知识库。 先导入少量结构清晰、答案可核对的资料,检查解析和分段预览,等待向量化完成,再用真实问法做命中测试。不要一开始导入全部企业文件,否则格式、分段、模型、权限和资料冲突会同时出现。
第三步:创建简易智能体。 选择已验证的 LLM,关联知识库,配置系统/用户提示词。事实型助手至少要写清:只基于检索资料回答;资料不足时明确说明;不得编造制度和参数;关键结论给出知识来源。完成调试后"保存并发布",再从正式问答入口测试。
第四步:建立最小评测集。 至少包含四类问题:资料中有直接答案、需要组合多个片段、同义改写、资料中无答案。记录期望命中资料和答案关键点,后续修改分段、模型、检索参数或提示词时复用同一批问题。
4.3 生产环境使用离线安装和可恢复升级
官方 v2 安装文档推荐生产使用离线安装包。离线包允许在 install.conf 中配置安装目录、端口、数据库和 Redis 等,并提供脚本和 mkctl 管理命令:
bash
bash install.sh
mkctl status
上线前确认服务器规格、磁盘、Docker 版本、端口与安全组。升级前备份真实持久化目录或外部数据库,阅读变更说明,在测试环境验证模型连接、重新向量化需求、知识检索、工作流发布、嵌入和 API;升级后用同一套评测集回归。生产应固定经过验证的镜像版本,不要在没有测试和回滚方案时自动跟随浮动最新镜像。
五、发布集成与生产工程:从能演示到可运营
5.1 公开链接、嵌入和 OpenAI 兼容 API
智能体概览支持启停/重新生成公开链接,并生成全屏、移动端或浮窗嵌入代码。它适合官网帮助中心、内部知识门户和业务后台,但上线前应确认是否真的需要匿名公开访问、是否设置每客户端提问限制和嵌入白名单;重新生成链接会使旧入口失效。
API 接入时,从当前智能体概览创建 API Key,复制该实例实际生成的 Base URL,并打开同页 Swagger 核对字段。不同版本与自定义部署路径可能改变 URL,不能从旧文章硬抄固定接口。OpenAI 兼容调用示例:
bash
export MAXKB_CHAT_COMPLETIONS_URL='<从智能体概览复制的完整接口地址>'
export MAXKB_API_KEY='<该智能体的API-Key>'
curl "$MAXKB_CHAT_COMPLETIONS_URL" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MAXKB_API_KEY" \
-d '{
"model": "<按当前Swagger填写>",
"messages": [
{"role": "user", "content": "请概括这份制度的报销时限"}
],
"stream": false
}'
API Key 只保存在业务后端的密钥管理系统或受保护环境变量中,不能进入浏览器 JavaScript、移动端安装包、Git 仓库或截图。调用侧设置连接/读取超时、有限重试、并发和费用限制,并对错误信息脱敏。
5.2 用证据和指标运营 RAG
高质量知识问答不是上传一次文档就结束。应建立"问题---期望命中资料---答案关键点---是否应拒答"的评测集,覆盖同义问法、长问题、专有名词、多文档组合、冲突资料和无答案问题。每次只改变一类变量,才能判断改进来自文档、分段、检索、重排、提示词还是模型。
建议持续观察:
- 文档更新到可检索的延迟、解析/向量化失败率;
- 正确片段召回率、重排后的命中位置;
- 答案关键点命中率、知识来源正确率、无答案拒答率;
- 端到端时延、模型和工具错误率、工作流分支失败率;
- Token、模型费用、API 并发与用户反馈。
对话页的知识来源、点赞/点踩和工作流执行详情可以辅助定位个案,但要判断版本是否整体变好,仍需稳定测试集和汇总指标。
5.3 身份、资源权限与凭据边界
把 RAG 演示升级为长期运行的平台,除了回答准确,还要解决"谁能进入系统、能操作哪些资源、长连接和后台任务如何互不拖垮"。MaxKB 已实现认证、资源权限、流式传输、任务隔离、连接池和检索索引等机制,但代码参数不等于经过压测的容量承诺。
管理后台与智能体访问使用不同认证入口。 两类访问没有共用同一种凭证:
| 访问平面 | 认证入口 | 凭证 | 主要用途 |
|---|---|---|---|
| 平台管理 | TokenAuth |
UserToken |
用户、模型、知识库、智能体、工具和系统 API |
| 智能体对话 | ChatTokenAuth |
匿名对话令牌、Application API Key | 公开问答、嵌入、API 与 OpenAI 兼容接口 |
平台登录 Token 由 django.core.signing.dumps() 生成,不是 JWT。固定提交中的 TokenAuth 与登录序列化器显示,登录时还会把会话状态写入 Redis;后续请求既要通过签名校验,也要确认 Token 仍在缓存中,并重新检查账号启用状态和密码哈希。退出登录会删除 Redis Token,密码变化也会使旧会话失效。因此它是可由服务端撤销的有状态会话,Redis 不只是性能缓存,也是认证链的一部分。
密码校验工具使用 Django PBKDF2;旧版 32 位 MD5 只作为兼容校验,成功登录后会升级,不是继续用 MD5 保存新密码。登录失败计数使用缓存原子 incr,锁键使用 cache.add;不过部分账户锁策略受许可证控制,不能笼统归为所有版本能力。对话 API Key 则检查启用、永久和过期状态,OpenAI 兼容接口还会确认 URL 中的 application_id 与 Key 绑定对象一致。
权限路径检查与资源级数据过滤。 MaxKB 的权限不是单纯判断管理员,而是将功能、操作和资源路径编码在一起:
text
APPLICATION:READ:/WORKSPACE/default
APPLICATION:READ+EDIT:/WORKSPACE/default/APPLICATION/<application_id>
KNOWLEDGE:READ:/WORKSPACE/default/KNOWLEDGE/<knowledge_id>
WORKSPACE_MANAGE:/WORKSPACE/default
完整链路为:
text
Bearer Token
→ TokenAuth 识别用户
→ get_auth() 汇总角色和权限
→ has_permissions() 检查接口准入
→ Serializer / SQL 再过滤用户可见资源
→ 执行业务操作
WorkspaceUserResourcePermission 记录工作空间、用户、资源类型、资源 ID、授权方式和权限列表,可覆盖智能体、知识库、工具、模型及相关文件夹。权限不是只控制菜单:接口层先检查操作权限,列表查询再联合授权表过滤用户可见资源;批量操作还会对资源 ID 再检查,权限更新后清理权限缓存。
社区版与 X-Pack 需要分开说明。公开 CE 代码可以确认默认工作空间和其中的用户级 VIEW/MANAGE 资源授权;多工作空间、自定义角色、角色映射和跨空间共享等通过 DatabaseModelManage 预留扩展契约,完整 X-Pack 模型实现不在公开 CE 仓库。因此可以分析扩展接口,不能把官方企业版架构图中的全部能力都声称为已经从社区源码验证。
模型和工具凭据的存储边界。 rsa_util.py、模型序列化器和工具序列化器表明,模型 credential 与 Tool init_params 并不是直接以明文 JSON 写入业务表:创建或修改时,序列化器调用 rsa_long_encrypt() 后再保存,读取和执行时才在服务端解密;返回管理界面时,密码字段还会被掩码处理。RSA 密钥对由系统生成并保存在 SystemSetting,私钥导出使用源码中的固定口令 mac_kb_password 保护。因此这套设计能避免数据库业务字段直接暴露 API Key,但密钥材料与密文仍由同一套应用和数据库管理,它不是外部 KMS、HSM 或独立密钥托管;生产环境仍应保护数据库、备份、应用运行权限并定期轮换第三方凭据。
5.4 并发、后台任务与容量边界
Web 服务使用线程化请求处理,工作流分支另在进程内并行。 生产入口使用 Gunicorn WSGI gthread,每个 Worker 配置 200 个线程,Worker 数可调整。简易智能体和高级工作流通过 Django StreamingHttpResponse 输出 SSE:
text
客户端
→ Gunicorn gthread Worker
→ Django / DRF
→ PipelineManage 或 WorkflowManage
→ 模型、知识库与工具
→ StreamingHttpResponse 持续返回事件
SSE 改善首字延迟,却会持续占用 WSGI 工作线程;200 是线程上限,不代表 200 个稳定模型并发。模型供应商配额、数据库连接、Redis 连接、CPU 和内存仍会限制容量。
工作流内部另有 ThreadPoolExecutor(max_workers=200)。当一个节点产生多个可执行下游分支时,分支会并行提交,再由汇合逻辑等待。它描述的是"单次工作流内的分支并行",不是平台总并发;线程池属于进程内对象,阻塞模式还有 Future 状态轮询,不能写成全链路 ASGI 异步事件架构。
后台任务、锁和数据层容量。 Celery 默认 Worker 将向量化、分词、问题生成、Web 同步、长期记忆和定时任务与 Web 请求隔离;Redis 同时作为 Broker、结果后端和 celery-once 锁存储。QueueOnce 与 Redis Lock 能减少相同资源重复执行,但锁没有自动续租,也不是分布式事务。长期记忆提取没有看到基于 (application_id, chat_user_id) 的 QueueOnce、Redis Lock、行锁或版本号,并发提取可能出现后写覆盖,这属于需要额外验证的工程边界。
PostgreSQL 使用连接池,公开默认配置包含基础池 20、最大溢出 80;Redis 默认最大连接数为 100。关键词字段使用 GIN;索引创建逻辑显示,向量维度低于 2000 时,向量表使用按知识库过滤的 HNSW。Redis Sentinel 只是配置支持,不代表默认容器已经形成高可用集群;数据库也没有在公开源码中展示读写分离、分片或多主实现。
源码没有提供以下完整能力或证据:
- DRF 全局
RateThrottle、令牌桶或漏桶式 QPS 限流; - 面向模型供应商的统一并发信号量和请求背压;
- 数据库读写分离、自动故障转移或分片;
- Kubernetes HPA 或按队列长度自动扩缩容;
- 可复现的并发用户数、QPS、P95 时延和稳定性压测报告。
ApplicationAccessToken.access_num 是匿名/对话用户每日访问配额,不是按秒限流器,其更新也不是数据库原子 F() 自增。因而最准确的结论是:MaxKB 具备线程化服务、SSE、工作流分支并行、Celery 长任务隔离、Redis 去重锁、连接池以及 HNSW/GIN 索引优化(HNSW 受向量维度条件限制),但不能仅凭这些配置宣称已经验证了某个高并发指标。
5.5 生产治理、问题定位与许可
落地时还应补齐以下运行治理:
- 账号与网络:修改默认管理员密码;管理端和原始端口只向受控网络开放;使用 HTTPS 和必要的身份网关。
- 数据边界:私有部署不等于数据必然不出网;公网模型仍可能接收问题、提示词和检索片段。
- 模型与工具密钥:密钥按环境隔离和轮换,日志不得打印完整值;工具启动参数与运行输入分开管理。
- 工具最小权限:数据库、HTTP、MCP 和代码工具采用白名单、只读/最小权限、超时、异常分支和审计;高风险写操作增加人工确认。
- 限流与背压:在网关或业务接入层补充 QPS、单用户并发、模型配额和排队策略,不把每日访问次数当作限流。
- 任务可观测性:监控容器、磁盘、数据库/Redis 连接、Celery 积压、模型时延、触发器记录、工具错误率和费用。
- 备份恢复:覆盖真实卷、外部数据库和必要配置,并定期做恢复演练;只有备份文件、没有恢复验证,不算可用备份。
- 版本治理:发布前保存测试结果和依赖关系;升级经过测试、备份、发布和回滚流程。
- 开源许可 :社区源码采用 GPL-3.0;修改或分发前阅读
LICENSE,商业授权与 X-Pack 边界向官方确认。
常见问题可按下表快速定位:
| 问题 | 首要检查 |
|---|---|
| 镜像拉取失败 | README 当前镜像地址、DNS/代理和仓库连通性;内网采用官方离线包 |
| 8080 无法访问 | 容器健康状态、日志、端口占用、防火墙/安全组和反向代理 |
| 上传返回 413 | Nginx 等代理请求体大小限制,例如 client_max_body_size |
| 文档任务长时间不结束 | Celery/后台任务状态、日志、Embedding 连接、磁盘与数据库 |
| 向量化成功但回答不准 | 命中测试、分段、Embedding、检索模式、Top K、阈值和 Rerank |
| 工作流调试正确但正式入口没变化 | 是否成功发布、入口是否引用正确智能体版本 |
| 升级后像"数据丢失" | 新旧容器宿主机挂载是否一致,外部数据库是否仍指向原实例 |
| API 未授权或跨域 | 当前 Base URL、Key 状态、Bearer 格式、允许来源和代理路径 |
六、适用场景与总结:循序渐进地落地,而不是一次堆满功能
MaxKB 适合产品手册、制度和运维文档的内部知识问答,也适合官网客服、教育研究资料助手、需要多模态节点的内容处理,以及依赖条件分支、外部数据、MCP 或定时/Webhook 的流程型智能体。对于已有门户或业务系统、希望通过嵌入或 OpenAI 兼容 API 快速增加 AI 能力的团队,它能减少从零开发管理后台、知识库、工作流与发布入口的成本。
它也有明确边界。如果需求只是单个静态页面上的轻量聊天,完整平台可能偏重;如果要求跨地域高可用、复杂人工坐席协同、极细粒度数据权限或强监管审计,则需要验证对应版本能力,并在 MaxKB 之外设计身份网关、审计、监控、容量和灾备。开源和可私有部署不等于所有治理能力天然具备。
推荐的落地顺序是:
- 选择一个答案边界清晰、资料质量较高的场景;
- 用少量文档打通 LLM、Embedding、知识库和简易智能体;
- 建立评测集,先解决解析、分段、召回和拒答问题;
- 确有业务逻辑需求时再加入高级工作流、工具、MCP 和触发器;
- 最后补齐 HTTPS、权限、限流、监控、备份、回滚和成本治理。
从技术视角看,MaxKB 的核心价值不是某一个模型或某一种检索算法,而是把文档生产、RAG、模型适配、流程编排、工具调用、异步任务、数据存储和发布接入组织为一条工程化链路。真正决定生产质量的,仍然是知识治理、证据驱动的评测体系和可靠运维。
参考资料
- MaxKB GitHub 仓库:https://github.com/cmyk-labs/MaxKB
- MaxKB 官方 GitHub 仓库:https://github.com/1Panel-dev/MaxKB
- MaxKB 官方文档:https://maxkb.cn/docs/v2/