# ragflow-plus - Doramagic AI Context Pack

> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。

## 充分原则

- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。
- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。

## 给宿主 AI 的使用方式

你正在读取 Doramagic 为 ragflow-plus 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。

## Claim 消费规则

- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。
- **事实最低状态**：`supported`
- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。
- `weak`：只能作为低置信度线索，必须要求用户继续核实。
- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。
- `unverified`：不得作为事实使用，应明确说证据不足。
- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。

## 它最适合谁

- **想在安装前理解开源项目价值和边界的用户**：当前证据主要来自项目文档。 证据：`README.md` Claim：`clm_0002` supported 0.86

## 它能做什么

- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`docs/quickstart/README.md` Claim：`clm_0001` supported 0.86

## 怎么开始

- `git clone https://github.com/zstar1003/ragflow-plus.git` 证据：`docs/quickstart/README.md` Claim：`clm_0003` supported 0.86

## 继续前判断卡

- **当前建议**：仅建议沙盒试装
- **为什么**：项目存在安装命令、宿主配置或本地写入线索，不建议直接进入主力环境，应先在隔离环境试装。

### 30 秒判断

- **现在怎么做**：仅建议沙盒试装
- **最小安全下一步**：先跑 Prompt Preview；若仍要安装，只在隔离环境试装
- **先别相信**：真实输出质量不能在安装前相信。
- **继续会触碰**：命令执行、本地环境或项目文件、宿主 AI 上下文

### 现在可以相信

- **适合人群线索：想在安装前理解开源项目价值和边界的用户**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86
- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`docs/quickstart/README.md` Claim：`clm_0001` supported 0.86
- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`docs/quickstart/README.md` Claim：`clm_0003` supported 0.86

### 现在还不能相信

- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。
- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。
- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。
- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。
- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。
- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。
- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`docs/quickstart/README.md`

### 继续会触碰什么

- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`docs/quickstart/README.md`
- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`docs/quickstart/README.md`
- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。

### 最小安全下一步

- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）
- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）
- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）

### 退出方式

- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。
- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。
- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。

## 哪些只能预览

- 解释项目适合谁和能做什么
- 基于项目文档演示典型对话流程
- 帮助用户判断是否值得安装或继续研究

## 哪些必须安装后验证

- 真实安装 Skill、插件或 CLI
- 执行脚本、修改本地文件或访问外部服务
- 验证真实输出质量、性能和兼容性

## 边界与风险判断卡

- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0004` inferred 0.45
- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`docs/quickstart/README.md` Claim：`clm_0005` supported 0.86
- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。
- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。
- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。

## 开工前工作上下文

### 加载顺序

- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。
- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。
- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。
- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。
- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。

### 任务路由

- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`docs/quickstart/README.md` Claim：`clm_0001` supported 0.86

### 上下文规模

- 文件总数：1108
- 重要文件覆盖：40/1108
- 证据索引条目：66
- 角色 / Skill 条目：12

### 证据不足时的处理

- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。
- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。
- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。
- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。

## Prompt Recipes

### 适配判断

- 目标：判断这个项目是否适合用户当前任务。
- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。

```text
请基于 ragflow-plus 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。
```

### 安装前体验

- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。
- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。

```text
请把 ragflow-plus 当作安装前体验资产，而不是已安装工具或真实运行环境。

请严格输出四段：
1. 先问我 3 个必要问题。
2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。
3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。
4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。

硬性边界：
- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。
- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。
- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。
- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。
- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。
- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。

```

### 角色 / Skill 选择

- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。
- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。

```text
请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。
```

### 风险预检

- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。
- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。

```text
请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。
```

### 宿主 AI 开工指令

- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。
- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。

```text
请基于 ragflow-plus 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。
```

## 角色 / Skill 索引

- 共索引 12 个角色 / Skill / 项目文档条目。

- **🌟 简介**（project_doc）：Ragflow-Plus 是一个基于 Ragflow 的二次开发项目，目的是解决实际应用中的一些问题，主要有以下特点： 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/README.md`
- **目录**（project_doc）：本项目采用了和ragflow一致的api接口，python的api接口如下。 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/api/README.md`
- **开发博客**（project_doc）：1. Ragflow技术栈分析及二次开发指南 2. 【Ragflow】2. rag检索原理和效率解析 3. 【Ragflow】3. 给聊天界面打个美化补丁 4. 【Ragflow】4. 增加文档撰写功能，实现全新交互模式 5. 【Ragflow】5. 看完Python API文档，竟然成为了官方仓库的Contributor 6. 【Ragflow】6. Ragflow-plus重磅更新：增加用户后台管理系统 7. 【Ragflow】7. Ragflow-plus和Ragflow有什么关系？主流问题Q&A 8. 【Ragflow】8. 基于ragflow API 搭建极简聊天Web界面 9. 【Ragflow】9. 问答为什么比搜索响应慢？从源码角度深入分析 10. 【Ragflow】10. 助理配置参数详细解析 / 模型响应加速方法 11. 【Ragflow】11. 文件解析流程分析 / 批量解析实现 12. 【Ragflow… 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/blog/README.md`
- **Docker镜像构建**（project_doc）：构建后台镜像前，需先将模型文件放置到 management 文件夹中。 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/build/README.md`
- **常见问题 FAQ**（project_doc）：- Docker Compose 推荐 : - GPU 版本: docker compose -f docker/docker-compose gpu.yml up -d - CPU 版本: docker compose -f docker/docker-compose.yml up -d - 源码运行: 请参考“快速开始”部分。 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/question/README.md`
- **快速开始**（project_doc）：- 高校/企业等事业单位团队，需要构建一系列中心知识库通过在线API，增强现有大模型的回答效果。 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/quickstart/README.md`
- **进阶技巧**（project_doc）：本项目提供了gpu部署的方案，可通过独立显卡，大大加速文档解析速度，预留空余显存需 6GB。 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/skill/README.md`
- **🌟 简介**（project_doc）：Ragflow-Plus 是一个基于 Ragflow 的二次开发项目，目的是解决实际应用中的一些问题，主要有以下特点： 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`
- **目录说明**（project_doc）：- common/assets/icons/preserve-color 目录下存放带颜色的 svg icon 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`management/web/src/common/assets/icons/preserve-color/README.md`
- **ragflow-sdk**（project_doc）：build and publish python SDK to pypi.org 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`sdk/python/README.md`
- **贡献指南**（project_doc）：本文档提供了向 RAGFlow-Plus 提交贡献的指导原则和主要注意事项。 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CONTRIBUTING.md`
- **Sidebar**（project_doc）：- 快速开始 quickstart/ - 进阶技巧 skill/ - API接口 api/ - 构建镜像 build/ - 博客系列 blog/ - 常见问题 question/ 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/_sidebar.md`

## 证据索引

- 共索引 66 条证据。

- **🌟 简介**（documentation）：Ragflow-Plus 是一个基于 Ragflow 的二次开发项目，目的是解决实际应用中的一些问题，主要有以下特点： 证据：`docs/README.md`
- **目录**（documentation）：本项目采用了和ragflow一致的api接口，python的api接口如下。 证据：`docs/api/README.md`
- **开发博客**（documentation）：1. Ragflow技术栈分析及二次开发指南 2. 【Ragflow】2. rag检索原理和效率解析 3. 【Ragflow】3. 给聊天界面打个美化补丁 4. 【Ragflow】4. 增加文档撰写功能，实现全新交互模式 5. 【Ragflow】5. 看完Python API文档，竟然成为了官方仓库的Contributor 6. 【Ragflow】6. Ragflow-plus重磅更新：增加用户后台管理系统 7. 【Ragflow】7. Ragflow-plus和Ragflow有什么关系？主流问题Q&A 8. 【Ragflow】8. 基于ragflow API 搭建极简聊天Web界面 9. 【Ragflow】9. 问答为什么比搜索响应慢？从源码角度深入分析 10. 【Ragflow】10. 助理配置参数详细解析 / 模型响应加速方法 11. 【Ragflow】11. 文件解析流程分析 / 批量解析实现 12. 【Ragflow】12. Ragflow-Plus管理系统v0.1.1：增加团队管理和用户配置功能 13. 【Ragflow】13. Deepdoc效果一言难尽，MinerU解析降维打击 14. 【Ragflow】14. MinerU解析脚本，接入ragflow知识库 15. 【Ragflow】15. Ragflow-Plus管理系统v0.1.2：小升级，连夜修复若干问题 16. 【Ragflow】16. Ragflow-Plus管理系统开发日志：重塑文件管理单元 17. 【Ragflow】17. Ragflow-Plus开发日志：增加知识库管理功能 / 支持Miner… 证据：`docs/blog/README.md`
- **Docker镜像构建**（documentation）：构建后台镜像前，需先将模型文件放置到 management 文件夹中。 证据：`docs/build/README.md`
- **常见问题 FAQ**（documentation）：- Docker Compose 推荐 : - GPU 版本: docker compose -f docker/docker-compose gpu.yml up -d - CPU 版本: docker compose -f docker/docker-compose.yml up -d - 源码运行: 请参考“快速开始”部分。 证据：`docs/question/README.md`
- **快速开始**（documentation）：- 高校/企业等事业单位团队，需要构建一系列中心知识库通过在线API，增强现有大模型的回答效果。 证据：`docs/quickstart/README.md`
- **进阶技巧**（documentation）：本项目提供了gpu部署的方案，可通过独立显卡，大大加速文档解析速度，预留空余显存需 6GB。 证据：`docs/skill/README.md`
- **🌟 简介**（documentation）：Ragflow-Plus 是一个基于 Ragflow 的二次开发项目，目的是解决实际应用中的一些问题，主要有以下特点： 证据：`README.md`
- **目录说明**（documentation）：- common/assets/icons/preserve-color 目录下存放带颜色的 svg icon 证据：`management/web/src/common/assets/icons/preserve-color/README.md`
- **ragflow-sdk**（documentation）：build and publish python SDK to pypi.org 证据：`sdk/python/README.md`
- **Package**（package_manifest）：{ "private": true, "author": "bill", "scripts": { "build": "umi build", "dev": "cross-env UMI DEV SERVER COMPRESS=none umi dev", "postinstall": "umi setup", "lint": "umi lint --eslint-only", "prepare": "cd .. && husky web/.husky", "setup": "umi setup", "start": "pnpm run dev", "test": "jest --no-cache --coverage" }, "lint-staged": { " .{js,jsx,ts,tsx,css,less,json}": "prettier --write --ignore-unknown" }, "dependencies": { "@ant-design/icons": "^5.2.6", "@ant-design/pro-components": "^2.6.46", "@ant-design/pro-layout": "^7.17.16", "@antv/g": "^6.1.21", "@antv/g2": "^5.2.11", "@antv/g6": "^5.0.44", "@hookform/resolvers": "^3.9.1", "@js-preview/excel": "^1.7.8", "@lexical/code": "^0.27.1", "@… 证据：`web/package.json`
- **Package**（package_manifest）：{ "name": "v3-admin-vite", "type": "module", "version": "5.0.0-beta.5", "description": "A crafted admin template, built with Vue3, Vite, TypeScript, Element Plus, and more", "author": "pany https://github.com/pany-ang ", "repository": "https://github.com/un-pany/v3-admin-vite", "scripts": { "dev": "vite", "build:staging": "vue-tsc && vite build --mode production", "build": "vue-tsc && vite build", "preview": "vite preview", "lint": "eslint . --fix", "prepare": "husky", "test": "vitest" }, "dependencies": { "@element-plus/icons-vue": "2.3.1", "axios": "1.8.4", "dayjs": "1.11.13", "element-plus": "2.9.7", "js-cookie": "3.0.5", "lodash-es": "4.17.21", "mitt": "3.0.1", "normalize.css": "8.0.1",… 证据：`management/web/package.json`
- **贡献指南**（documentation）：本文档提供了向 RAGFlow-Plus 提交贡献的指导原则和主要注意事项。 证据：`CONTRIBUTING.md`
- **License**（source_file）：GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 证据：`LICENSE`
- **Sidebar**（documentation）：- 快速开始 quickstart/ - 进阶技巧 skill/ - API接口 api/ - 构建镜像 build/ - 博客系列 blog/ - 常见问题 question/ 证据：`docs/_sidebar.md`
- **Init**（source_file）：env path = Path get root folder / "docker" / ".env" 证据：`api/__init__.py`
- **Jest.Config**（source_file）：import { Config, configUmiAlias, createConfig } from 'umi/test'; 证据：`web/jest.config.ts`
- **Init**（source_file）：all = "app" ⋮---- app = Flask name swagger config = { swagger = Swagger ⋮---- login manager = LoginManager ⋮---- def search pages path pages dir ⋮---- app path list = api path list = ⋮---- def register page page path ⋮---- path = f"{page path}" page name = page path.stem.rstrip " app" module name = ".".join spec = spec from file location module name, page path page = module from spec spec ⋮---- page name = getattr page, "page name", page name sdk path = "\\sdk\\" if sys.platform.startswith "win" else "/sdk/" url prefix = ⋮---- pages dir = client urls prefix = ⋮---- @login manager.request loader def load user web request ⋮---- jwt = Serializer secret key=settings.SECRET KEY authorization = w… 证据：`api/apps/__init__.py`
- **Api App**（source_file）：@manager.route "/new token", methods= "POST" @login required def new token ⋮---- req = request.json ⋮---- tenants = UserTenantService.query user id=current user.id ⋮---- tenant id = tenants 0 .tenant id obj = { ⋮---- @manager.route "/token list", methods= "GET" @login required def token list ⋮---- id = request.args "dialog id" if "dialog id" in request.args else request.args "canvas id" objs = APITokenService.query tenant id=tenants 0 .tenant id, dialog id=id ⋮---- @manager.route "/rm", methods= "POST" @validate request "tokens", "tenant id" @login required def rm ⋮---- @manager.route "/stats", methods= "GET" @login required def stats ⋮---- objs = API4ConversationService.stats res = { ⋮----… 证据：`api/apps/api_app.py`
- **只更新img id，不需要重新计算嵌入**（source_file）：@manager.route "/list", methods= "POST" @login required @validate request "doc id" def list chunk ⋮---- req = request.json doc id = req "doc id" page = int req.get "page", 1 size = int req.get "size", 30 question = req.get "keywords", "" ⋮---- tenant id = DocumentService.get tenant id req "doc id" ⋮---- kb ids = KnowledgebaseService.get kb ids tenant id query = {"doc ids": doc id , "page": page, "size": size, "question": question, "sort": True} ⋮---- sres = settings.retrievaler.search query, search.index name tenant id , kb ids, highlight=True res = {"total": sres.total, "chunks": , "doc": doc.to dict } ⋮---- d = { ⋮---- @manager.route "/get", methods= "GET" @login required def get ⋮---- ch… 证据：`api/apps/chunk_app.py`
- **处理旧版Word文档 .doc**（source_file）：DOCX AVAILABLE = True ⋮---- DOCX AVAILABLE = False ⋮---- DOC AVAILABLE = True ⋮---- DOC AVAILABLE = False def extract file content file content bytes, filename, content type ⋮---- file ext = filename.lower .split '.' -1 if '.' in filename else '' 处理旧版Word文档 .doc ⋮---- 处理新版Word文档 .docx ⋮---- doc stream = io.BytesIO file content bytes doc = Document doc stream paragraphs = ⋮---- row text = ⋮---- 处理文本文件 ⋮---- 尝试多种编码 encodings = 'utf-8', 'gbk', 'gb2312', 'big5', 'latin1' ⋮---- 如果所有编码都失败，使用错误忽略模式 ⋮---- 处理PDF文件 ⋮---- 其他文件类型 ⋮---- 尝试作为文本文件处理 ⋮---- 先尝试UTF-8 text content = file content bytes.decode 'utf-8' 检查是否包含过多的非打印字符（可能是二进制文件） non printable ratio = sum 1 for c in text content if ord c 0.3: 如果超过3… 证据：`api/apps/conversation_app.py`
- **Dialog App**（source_file）：@manager.route "/set", methods= "POST" @login required def set dialog ⋮---- req = request.json dialog id = req.get "dialog id" name = req.get "name", "New Dialog" description = req.get "description", "一个智慧小帮手" icon = req.get "icon", "" top n = req.get "top n", 6 top k = req.get "top k", 1024 rerank id = req.get "rerank id", "" ⋮---- similarity threshold = req.get "similarity threshold", 0.1 vector similarity weight = req.get "vector similarity weight", 0.3 llm setting = req.get "llm setting", {} default prompt = { prompt config = req.get "prompt config", default prompt ⋮---- kbs = KnowledgebaseService.get by ids req.get "kb ids", embd ids = TenantLLMService.split model name and factory kb.e… 证据：`api/apps/dialog_app.py`
- **Document App**（source_file）：@manager.route "/upload", methods= "POST" @login required @validate request "kb id" def upload ⋮---- kb id = request.form.get "kb id" ⋮---- file objs = request.files.getlist "file" ⋮---- files = f 0 for f in files remove the blob ⋮---- @manager.route "/web crawl", methods= "POST" @login required @validate request "kb id", "name", "url" def web crawl ⋮---- name = request.form.get "name" url = request.form.get "url" ⋮---- blob = html2pdf url ⋮---- root folder = FileService.get root folder current user.id pf id = root folder "id" ⋮---- kb root folder = FileService.get kb folder current user.id kb folder = FileService.new a file from kb kb.tenant id, kb.name, kb root folder "id" ⋮---- filename… 证据：`api/apps/document_app.py`
- **File2Document App**（source_file）：@manager.route '/convert', methods= 'POST' @login required @validate request "file ids", "kb ids" def convert ⋮---- req = request.json kb ids = req "kb ids" file ids = req "file ids" file2documents = ⋮---- file ids list = file id ⋮---- file ids list = FileService.get all innermost file ids file id, ⋮---- informs = File2DocumentService.get by file id id ⋮---- doc id = inform.document id ⋮---- tenant id = DocumentService.get tenant id doc id ⋮---- doc = DocumentService.insert { file2document = File2DocumentService.insert { ⋮---- @manager.route '/rm', methods= 'POST' @login required @validate request "file ids" def rm ⋮---- informs = File2DocumentService.get by file id file id 证据：`api/apps/file2document_app.py`
- **split file name path**（source_file）：@manager.route '/upload', methods= 'POST' @login required def upload ⋮---- pf id = request.form.get "parent id" ⋮---- root folder = FileService.get root folder current user.id pf id = root folder "id" ⋮---- file objs = request.files.getlist 'file' ⋮---- file res = ⋮---- MAX FILE NUM PER USER = int os.environ.get 'MAX FILE NUM PER USER', 0 ⋮---- split file name path ⋮---- file obj names = file.name, file obj.filename ⋮---- full path = '/' + file obj.filename file obj names = full path.split '/' file len = len file obj names get folder file id list = FileService.get id list by id pf id, file obj names, 1, pf id len id list = len file id list create folder ⋮---- last folder = FileService.creat… 证据：`api/apps/file_app.py`
- **获取知识库下的所有文档**（source_file）：@manager.route "/create", methods= "post" @login required @validate request "name" def create ⋮---- req = request.json dataset name = req "name" ⋮---- dataset name = dataset name.strip dataset name = duplicate name KnowledgebaseService.query, name=dataset name, tenant id=current user.id, status=StatusEnum.VALID.value ⋮---- @manager.route "/update", methods= "post" @login required @validate request "kb id", "name", "description", "permission", "parser id" @not allowed parameters "id", "tenant id", "created by", "create time", "update time", "create date", "update date", "created by" def update ⋮---- kb = kb.to dict ⋮---- @manager.route "/detail", methods= "GET" @login required def detail ⋮--… 证据：`api/apps/kb_app.py`
- **TODO: check other type of models**（source_file）：@manager.route '/factories', methods= 'GET' @login required def factories ⋮---- fac = LLMFactoriesService.get all fac = f.to dict for f in fac if f.name not in "Youdao", "FastEmbed", "BAAI" llms = LLMService.get all mdl types = {} ⋮---- @manager.route '/set api key', methods= 'POST' @login required @validate request "llm factory", "api key" def set api key ⋮---- req = request.json ⋮---- factory = req "llm factory" msg = "" ⋮---- mdl = EmbeddingModel factory ⋮---- embd passed = True ⋮---- mdl = ChatModel factory ⋮---- chat passed = True ⋮---- mdl = RerankModel factory ⋮---- rerank passed = True ⋮---- msg = '' ⋮---- llm config = { ⋮---- @manager.route '/add llm', methods= 'POST' @login requir… 证据：`api/apps/llm_app.py`
- **Minio App**（source_file）：@manager.route "/endpoint", methods= "GET" def minio ⋮---- host = os.getenv "MINIO VISIT HOST", "localhost" ⋮---- host = "http://" + host port = os.getenv "MINIO PORT", "9000" 证据：`api/apps/minio_app.py`
- **Chat**（source_file）：@manager.route '/chats', methods= 'POST' @token required def create tenant id ⋮---- req = request.json ids = i for i in req.get "dataset ids", if i ⋮---- kbs = KnowledgebaseService.accessible kb id=kb id, user id=tenant id ⋮---- kbs = KnowledgebaseService.query id=kb id kb = kbs 0 ⋮---- kbs = KnowledgebaseService.get by ids ids if ids else embd ids = TenantLLMService.split model name and factory kb.embd id 0 for kb in kbs embd count = list set embd ids ⋮---- llm = req.get "llm" ⋮---- prompt = req.get "prompt" key mapping = {"parameters": "variables", key list = "similarity threshold", "vector similarity weight", "top n", "rerank id","top k" ⋮---- value rerank model = "BAAI/bge-reranker-v2-m… 证据：`api/apps/sdk/chat.py`
- **Dataset**（source_file）：@manager.route "/datasets", methods= "POST" @token required def create tenant id ⋮---- req = request.json ⋮---- permission = req.get "permission" chunk method = req.get "chunk method" parser config = req.get "parser config" ⋮---- valid permission = "me", "team" valid chunk method = check validation = valid ⋮---- valid embedding models = embd model = LLMService.query ⋮---- embd model=TenantLLMService.query tenant id=tenant id,model type="embedding", llm name=req.get "embedding model" ⋮---- key mapping = { mapped keys = { ⋮---- flds = list req.keys ⋮---- renamed data = {} ⋮---- new key = key mapping.get key, key ⋮---- @manager.route "/datasets", methods= "DELETE" @token required def delete te… 证据：`api/apps/sdk/dataset.py`
- **total size**（source_file）：MAXIMUM OF UPLOADING FILES = 256 class Chunk BaseModel ⋮---- id: str = "" content: str = "" document id: str = "" docnm kwd: str = "" important keywords: list = Field default factory=list questions: list = Field default factory=list question tks: str = "" image id: str = "" available: bool = True positions: list list int = Field default factory=list ⋮---- @validator 'positions' def validate positions cls, value ⋮---- @manager.route "/datasets/ /documents", methods= "POST" @token required def upload dataset id, tenant id ⋮---- file objs = request.files.getlist "file" ⋮---- ''' total size total size = 0 for file obj in file objs: file obj.seek 0, os.SEEK END total size += file obj.tell file o… 证据：`api/apps/sdk/doc.py`
- **Filter system and non-sense assistant messages**（source_file）：@manager.route "/chats/ /sessions", methods= "POST" @token required def create tenant id, chat id ⋮---- req = request.json ⋮---- dia = DialogService.query tenant id=tenant id, id=req "dialog id" , status=StatusEnum.VALID.value ⋮---- conv = { ⋮---- conv = conv.to dict ⋮---- @manager.route "/chats/ /sessions/ ", methods= "PUT" @token required def update tenant id, chat id, session id ⋮---- conv id = session id conv = ConversationService.query id=conv id, dialog id=chat id ⋮---- @manager.route "/chats/ /completions", methods= "POST" @token required def chat completion tenant id, chat id ⋮---- req = {"question": ""} ⋮---- resp = Response rag completion tenant id, chat id, req , mimetype="text/e… 证据：`api/apps/sdk/session.py`
- **System App**（source_file）：@manager.route "/version", methods= "GET" @login required def version ⋮---- @manager.route "/status", methods= "GET" @login required def status ⋮---- res = {} st = timer ⋮---- task executor heartbeats = {} ⋮---- task executors = REDIS CONN.smembers "TASKEXE" now = datetime.now .timestamp ⋮---- heartbeats = REDIS CONN.zrangebyscore task executor id, now - 60 30, now heartbeats = json.loads heartbeat for heartbeat in heartbeats ⋮---- @manager.route "/new token", methods= "POST" @login required def new token ⋮---- tenants = UserTenantService.query user id=current user.id ⋮---- tenant id = tenant for tenant in tenants if tenant.role == 'owner' 0 .tenant id obj = { ⋮---- @manager.route "/token l… 证据：`api/apps/system_app.py`
- **Tenant App**（source_file）：@manager.route "/ /user/list", methods= "GET" @login required def user list tenant id ⋮---- users = UserTenantService.get by tenant id tenant id ⋮---- @manager.route '/ /user', methods= 'POST' @login required @validate request "email" def create tenant id ⋮---- req = request.json invite user email = req "email" invite users = UserService.query email=invite user email ⋮---- user id to invite = invite users 0 .id user tenants = UserTenantService.query user id=user id to invite, tenant id=tenant id ⋮---- user tenant role = user tenants 0 .role ⋮---- usr = invite users 0 .to dict usr = {k: v for k, v in usr.items if k in "id", "avatar", "email", "nickname" } ⋮---- @manager.route '/ /user/ ', me… 证据：`api/apps/tenant_app.py`
- **从Hugging Face加载模型**（source_file）：model = None tokenizer = None device = "cpu" def load translation model ⋮---- model name = "utrobinmv/t5 translate en ru zh small 1024" MODEL PATH = "./models" ⋮---- model = T5ForConditionalGeneration.from pretrained MODEL PATH tokenizer = T5Tokenizer.from pretrained MODEL PATH ⋮---- 从Hugging Face加载模型 ⋮---- model = T5ForConditionalGeneration.from pretrained model name tokenizer = T5Tokenizer.from pretrained model name ⋮---- def translate text text, source lang="zh", target lang="en" ⋮---- prefix = "translate to en: " ⋮---- prefix = "translate to zh: " ⋮---- prefix = f"translate to {target lang}: " src text = prefix + text 编码输入 input ids = tokenizer src text, return tensors="pt", max length=… 证据：`api/apps/translate_app.py`
- **Try to log in**（source_file）：@manager.route "/login", methods= "POST", "GET" def login ⋮---- email = request.json.get "email", "" users = UserService.query email=email ⋮---- password = request.json.get "password" ⋮---- password = decrypt password ⋮---- user = UserService.query user email, password ⋮---- response data = user.to json ⋮---- msg = "Welcome back!" ⋮---- @manager.route "/github callback", methods= "GET" def github callback ⋮---- res = requests.post res = res.json ⋮---- user info = user info from github session "access token" email address = user info "email" users = UserService.query email=email address user id = get uuid ⋮---- avatar = download img user info "avatar url" ⋮---- avatar = "" users = user regis… 证据：`api/apps/user_app.py`
- **Init**（source_file）：class StatusEnum Enum ⋮---- VALID = "1" INVALID = "0" class UserTenantRole StrEnum ⋮---- OWNER = 'owner' ADMIN = 'admin' NORMAL = 'normal' INVITE = 'invite' class TenantPermission StrEnum ⋮---- ME = 'me' TEAM = 'team' class SerializedType IntEnum ⋮---- PICKLE = 1 JSON = 2 class FileType StrEnum ⋮---- PDF = 'pdf' DOC = 'doc' VISUAL = 'visual' AURAL = 'aural' VIRTUAL = 'virtual' FOLDER = 'folder' OTHER = "other" class LLMType StrEnum ⋮---- CHAT = 'chat' EMBEDDING = 'embedding' SPEECH2TEXT = 'speech2text' IMAGE2TEXT = 'image2text' RERANK = 'rerank' TTS = 'tts' class ChatStyle StrEnum ⋮---- CREATIVE = 'Creative' PRECISE = 'Precise' EVENLY = 'Evenly' CUSTOM = 'Custom' class TaskStatus StrEnum ⋮-… 证据：`api/db/__init__.py`
- **Init**（source_file）：def duplicate name query func, kwargs ⋮---- fnm = kwargs "name" objs = query func kwargs ⋮---- ext = pathlib.Path fnm .suffix nm = re.sub r"%s$"%ext, "", fnm r = re.search r"\ 0-9 + \ $", nm c = 0 ⋮---- c = int r.group 1 nm = re.sub r"\ 0-9 +\ $", "", nm ⋮---- nm = f"{nm} {c} " 证据：`api/db/services/__init__.py`
- **load local config file**（source_file）：def conf realpath conf name ⋮---- conf path = f"conf/{conf name}" ⋮---- def read config conf name=SERVICE CONF ⋮---- local config = {} local path = conf realpath f'local.{conf name}' load local config file ⋮---- local config = file utils.load yaml conf local path ⋮---- global config path = conf realpath conf name global config = file utils.load yaml conf global config path ⋮---- CONFIGS = read config def show configs ⋮---- msg = f"Current configs, from {conf realpath SERVICE CONF }:" ⋮---- v = copy.deepcopy v ⋮---- def get base config key, default=None ⋮---- default = os.environ.get key.upper ⋮---- use deserialize safe module = get base config class BaseType ⋮---- def to dict self def to di… 证据：`api/utils/__init__.py`
- **App**（source_file）：app = Flask name ⋮---- ADMIN USERNAME = os.getenv "MANAGEMENT ADMIN USERNAME", "admin" ADMIN PASSWORD = os.getenv "MANAGEMENT ADMIN PASSWORD", "12345678" JWT SECRET = os.getenv "MANAGEMENT JWT SECRET", "your-secret-key" log dir = "logs" ⋮---- log file = os.path.join log dir, "parser.log" ⋮---- def generate token user info ⋮---- expire time = datetime.utcnow + timedelta hours=1 payload = { token = jwt.encode payload, JWT SECRET, algorithm="HS256" ⋮---- @app.route "/api/v1/auth/login", methods= "POST" def login ⋮---- data = request.get json username = data.get "username" password = data.get "password" ⋮---- token = generate token user info 证据：`management/server/app.py`
- **Init**（source_file）：users bp = Blueprint 'users', name , url prefix='/api/v1/users' teams bp = Blueprint 'teams', name , url prefix='/api/v1/teams' tenants bp = Blueprint 'tenants', name , url prefix='/api/v1/tenants' files bp = Blueprint 'files', name , url prefix='/api/v1/files' knowledgebase bp = Blueprint 'knowledgebases', name , url prefix='/api/v1/knowledgebases' conversation bp = Blueprint 'conversation', name , url prefix='/api/v1/conversation' ⋮---- def register routes app 证据：`management/server/routes/__init__.py`
- **Routes**（source_file）：@conversation bp.route "", methods= "GET" def get conversations ⋮---- user id = request.args.get "user id" page = int request.args.get "page", 1 size = int request.args.get "size", 20 sort by = request.args.get "sort by", "update time" sort order = request.args.get "sort order", "desc" ⋮---- @conversation bp.route "/ /messages", methods= "GET" def get messages conversation id ⋮---- size = int request.args.get "size", 30 证据：`management/server/routes/conversation/routes.py`
- **获取当前用户信息**（source_file）：UPLOAD FOLDER = "/data/uploads" ALLOWED EXTENSIONS = {"txt", "pdf", "png", "jpg", "jpeg", "gif", "doc", "docx", "xls", "xlsx"} def allowed file filename ⋮---- @files bp.route "/upload", methods= "POST" def upload file ⋮---- current user = get current user from token user id = current user.get 'user id' if current user else None files = request.files.getlist "files" upload result = upload files to server files, user id=user id ⋮---- @files bp.route "", methods= "GET", "OPTIONS" def get files ⋮---- 获取当前用户信息 ⋮---- current page = int request.args.get "currentPage", 1 page size = int request.args.get "size", 10 name filter = request.args.get "name", "" sort by = request.args.get "sort by", "crea… 证据：`management/server/routes/files/routes.py`
- **获取系统 Embedding 配置路由**（source_file）：@knowledgebase bp.route "", methods= "GET" def get knowledgebase list ⋮---- current user = get current user from token params = { ⋮---- result = KnowledgebaseService.get knowledgebase list params ⋮---- @knowledgebase bp.route "/ ", methods= "GET" def get knowledgebase detail kb id ⋮---- knowledgebase = KnowledgebaseService.get knowledgebase detail kb id=kb id ⋮---- @knowledgebase bp.route "", methods= "POST" def create knowledgebase ⋮---- data = request.json ⋮---- kb = KnowledgebaseService.create knowledgebase data ⋮---- @knowledgebase bp.route "/ ", methods= "PUT" def update knowledgebase kb id ⋮---- kb = KnowledgebaseService.update knowledgebase kb id=kb id, data ⋮---- @knowledgebase bp.r… 证据：`management/server/routes/knowledgebases/routes.py`
- **如果是团队负责人，只返回其自己的团队**（source_file）：@teams bp.route '', methods= 'GET' def get teams ⋮---- current user = get current user from token current page = int request.args.get 'currentPage', 1 page size = int request.args.get 'size', 10 team name = request.args.get 'name', '' sort by = request.args.get "sort by", "create time" sort order = request.args.get "sort order", "desc" 如果是团队负责人，只返回其自己的团队 tenant id = None ⋮---- tenant id = current user.get "tenant id" 调用服务函数获取分页和筛选后的团队数据 ⋮---- 返回符合前端期望格式的数据 ⋮---- 错误处理 ⋮---- @teams bp.route '/ ', methods= 'GET' def get team team id ⋮---- team = get team by id team id ⋮---- @teams bp.route '/ ', methods= 'DELETE' def delete team route team id ⋮---- """删除团队的API端点""" ⋮---- success = delete team… 证据：`management/server/routes/teams/routes.py`
- **调用服务函数获取分页和筛选后的租户数据**（source_file）：@tenants bp.route '', methods= 'GET' def get tenants ⋮---- current page = int request.args.get 'currentPage', 1 page size = int request.args.get 'size', 10 username = request.args.get 'username', '' 调用服务函数获取分页和筛选后的租户数据 ⋮---- 返回符合前端期望格式的数据 ⋮---- 错误处理 ⋮---- @tenants bp.route '/ ', methods= 'PUT' def update tenant route tenant id ⋮---- data = request.json success = update tenant tenant id=tenant id, tenant data=data 证据：`management/server/routes/tenants/routes.py`
- **调用服务函数获取分页和筛选后的用户数据**（source_file）：JWT SECRET = os.getenv "MANAGEMENT JWT SECRET", "your-secret-key" ⋮---- @users bp.route '', methods= 'GET' def get users ⋮---- current page = int request.args.get 'currentPage', 1 page size = int request.args.get 'size', 10 username = request.args.get 'username', '' email = request.args.get 'email', '' sort by = request.args.get "sort by", "create time" sort order = request.args.get "sort order", "desc" 调用服务函数获取分页和筛选后的用户数据 ⋮---- 返回符合前端期望格式的数据 ⋮---- "code": 0, 成功状态码 ⋮---- 错误处理 ⋮---- @users bp.route '/ ', methods= 'DELETE' def delete user route user id ⋮---- @users bp.route '', methods= 'POST' def create user route ⋮---- """创建用户的API端点""" data = request.json 创建用户 ⋮---- success = create user us… 证据：`management/server/routes/users/routes.py`
- **Init**（source_file）：db = MySQLDatabase class BaseModel Model ⋮---- create time = BigIntegerField null=True create date = CharField null=True update time = BigIntegerField null=True update date = CharField null=True class Meta ⋮---- database = db class Document BaseModel ⋮---- id = CharField primary key=True thumbnail = TextField null=True kb id = CharField index=True parser id = CharField null=True, index=True parser config = TextField null=True source type = CharField default="local", index=True type = CharField index=True created by = CharField null=True, index=True name = CharField null=True, index=True location = CharField null=True size = IntegerField default=0 token num = IntegerField default=0 chunk num… 证据：`management/server/services/files/models/__init__.py`
- **Init**（source_file）：logger = logging.getLogger name 证据：`management/server/services/knowledgebases/__init__.py`
- **Index**（source_file）：import { request } from "@/http/axios" export function updateTableDataApi data: Tables.CreateOrUpdateTableRequestData export function getTableDataApi params: Tables.TableRequestData 证据：`management/web/src/common/apis/configs/index.ts`
- **Type**（source_file）：export interface CreateOrUpdateTableRequestData { id?: number username: string chatModel?: string embeddingModel?: string } export interface TableRequestData { currentPage: number size: number username?: string } export interface TableData { id: number username: string chatModel: string embeddingModel: string createTime: string updateTime: string } export type TableResponseData = ApiResponseData 证据：`management/web/src/common/apis/configs/type.ts`
- **Index**（source_file）：import type { AxiosResponse } from "axios" import type { FileData, PageQuery, PageResult } from "./type" import { request } from "@/http/axios" import axios from "axios" export function getFileListApi params: PageQuery & export function downloadFileApi fileId: string, onDownloadProgress?: progressEvent: any = void : Promise export function cancelDownload export function deleteFileApi fileId: string export function batchDeleteFilesApi fileIds: string export function uploadFileApi formData: FormData 证据：`management/web/src/common/apis/files/index.ts`
- **Type**（source_file）：export interface FileData { id: string name: string size: number type: string kb id: string location: string create time?: number update time?: number create date?: string } export interface FileListResult { list: FileData total: number } export interface PageQuery { currentPage: number size: number sort by: string sort order: string } export interface PageResult { list: T total: number } export interface ApiResponse { code: number data: T message: string } 证据：`management/web/src/common/apis/files/type.ts`
- **Document**（source_file）：import { request } from "@/http/axios" interface UploadResponse { code: number message?: string data: any } export function getDocumentListApi params: { kb id: string currentPage: number size: number name?: string sort by: string sort order: string } export function getDocumentDetailApi id: string export function getDocumentParseProgress docId: any export function startDocumentParse docId: any export function uploadDocumentApi formData: FormData : Promise export function deleteDocumentApi docId: string export function batchDeleteDocumentsApi ids: string export function changeDocumentStatusApi id: string, status: string export function runDocumentParseApi id: string export function getDocume… 证据：`management/web/src/common/apis/kbs/document.ts`
- **Type**（source_file）：export interface FileData { id: string name: string size: number type: string kb id: string location: string create time?: number update time?: number } export interface FileListResult { list: FileData total: number } export interface PageQuery { currentPage: number size: number } export interface PageResult { list: T total: number } export interface ApiResponse { code: number data: T message: string } 证据：`management/web/src/common/apis/kbs/type.ts`
- **Index**（source_file）：import { request } from "@/http/axios" export function createTableDataApi data: Tables.CreateOrUpdateTableRequestData export function deleteTableDataApi id: string export function updateTableDataApi data: Tables.CreateOrUpdateTableRequestData export function getTableDataApi params: Tables.TableRequestData export function resetPasswordApi userId: string, password: string 证据：`management/web/src/common/apis/tables/index.ts`
- **Type**（source_file）：export interface CreateOrUpdateTableRequestData { id?: string username: string email?: string password?: string } export interface TableRequestData { currentPage: number size: number username?: string email?: string sort by: string sort order: string } export interface TableData { id: string username: string email: string createTime: string updateTime: string } export type TableResponseData = ApiResponseData 证据：`management/web/src/common/apis/tables/type.ts`
- **Index**（source_file）：import { request } from "@/http/axios" export function getTableDataApi params: Tables.TableRequestData export function getTeamMembersApi teamId: number export function addTeamMemberApi data: export function removeTeamMemberApi data: export function getUsersApi params?: object 证据：`management/web/src/common/apis/teams/index.ts`
- **Type**（source_file）：export interface CreateOrUpdateTableRequestData { id?: number username: string email?: string password?: string } export interface TableRequestData { currentPage: number size: number username?: string email?: string name?: string sort by: string sort order: string } export interface TableData { id: number username: string email: string createTime: string updateTime: string } export type TableResponseData = ApiResponseData 证据：`management/web/src/common/apis/teams/type.ts`
- **Index**（source_file）：import { request } from "@/http/axios" export function getCurrentUserApi 证据：`management/web/src/common/apis/users/index.ts`
- 其余 6 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。

## 宿主 AI 必须遵守的规则

- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`docs/README.md`, `docs/api/README.md`, `docs/blog/README.md`
- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`docs/README.md`, `docs/api/README.md`, `docs/blog/README.md`

## 用户开工前应该回答的问题

- 你准备在哪个宿主 AI 或本地环境中使用它？
- 你只是想先体验工作流，还是准备真实安装？
- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？

## 验收标准

- 所有能力声明都能回指到 evidence_refs 中的文件路径。
- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。
- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。

---

## Doramagic Context Augmentation

下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。

## Human Manual 骨架

使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。

宿主 AI 硬性规则：
- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。
- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。
- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。

- **项目概览与系统架构**：importance `high`
  - source_paths: README.md, docker/docker-compose.yml, docker/docker-compose-base.yml, Dockerfile, api/ragflow_server.py
- **知识库与文档解析（MinerU 集成）**：importance `high`
  - source_paths: management/server/services/knowledgebases/document_parser.py, management/server/services/knowledgebases/excel_parser.py, management/server/services/knowledgebases/service.py, management/server/services/knowledgebases/rag_tokenizer.py, management/server/services/knowledgebases/utils.py
- **后台管理系统与用户/团队/租户体系**：importance `high`
  - source_paths: management/server/app.py, management/server/routes/users/routes.py, management/server/routes/teams/routes.py, management/server/routes/tenants/routes.py, management/server/routes/conversation/routes.py
- **RAG 核心、对话与智能检索（GraphRAG / Agentic）**：importance `high`
  - source_paths: rag/nlp/search.py, rag/nlp/query.py, rag/nlp/term_weight.py, rag/nlp/synonym.py, rag/llm/chat_model.py

## Repo Inspection Evidence / 源码检查证据

- repo_clone_verified: true
- repo_inspection_verified: true
- repo_commit: `3f7aac2512f80a77cf0ad5c1f6e673f0fa39d63c`
- inspected_files: `Dockerfile`, `README.md`, `pyproject.toml`, `requirements.txt`, `docs/README.md`, `docs/_sidebar.md`, `docs/api/README.md`, `docs/blog/README.md`, `docs/build/README.md`, `docs/question/README.md`, `docs/quickstart/README.md`, `docs/skill/README.md`

宿主 AI 硬性规则：
- 没有 repo_clone_verified=true 时，不得声称已经读过源码。
- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。
- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。

## Doramagic Pitfall Constraints / 踩坑约束

这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。

### Constraint 1: 来源证据：[Bug]: docker部署报错

- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: docker部署报错
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/182 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 2: 来源证据：[Question]: 大哥请教一下图片显示这边接口的修改，原来的接口自动添加http和9000只适合IP地址，不适合域名

- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Question]: 大哥请教一下图片显示这边接口的修改，原来的接口自动添加http和9000只适合IP地址，不适合域名
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/185 | 来源讨论提到 python 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 3: 来源证据：[Question]: is there an English language option for the user management page

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[Question]: is there an English language option for the user management page
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/256 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 4: 来源证据：[Question]: 怎么修改聊天界面，左上角的图标和Ragflow-plus的标题？

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[Question]: 怎么修改聊天界面，左上角的图标和Ragflow-plus的标题？
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/233 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 5: 来源证据：[Question]: 文件上传问题

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[Question]: 文件上传问题
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/239 | 来源讨论提到 python 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 6: 来源证据：[Question]: 用户前台登录时提示：MaxConnectionsExceeded('Exceeded maximum connections.')

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[Question]: 用户前台登录时提示：MaxConnectionsExceeded('Exceeded maximum connections.')
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/257 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 7: 来源证据：[Question]: 管理端显示的嵌入模型和第一个用户配置的嵌入模型不一致

- Trigger: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[Question]: 管理端显示的嵌入模型和第一个用户配置的嵌入模型不一致
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/183 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 8: 来源证据：[Question]: 请问如何通过 db_models.py 新增加 user_tenant_kb 列表。

- Trigger: GitHub 社区证据显示该项目存在一个能力理解相关的待验证问题：[Question]: 请问如何通过 db_models.py 新增加 user_tenant_kb 列表。
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/250 | 来源讨论提到 python 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 9: 来源证据：[Bug]: 文档解析失败：Unknown column 'process_duation' in 'field list'

- Trigger: GitHub 社区证据显示该项目存在一个运行相关的待验证问题：[Bug]: 文档解析失败：Unknown column 'process_duation' in 'field list'
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/240 | 来源讨论提到 python 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 10: 来源证据：[Bug]: 登录ragflow时 一直要求进行身份验证

- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[Bug]: 登录ragflow时 一直要求进行身份验证
- Why it matters: 可能影响授权、密钥配置或安全边界。
- Evidence: community_evidence:github | https://github.com/zstar1003/ragflow-plus/issues/238 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。
