diff --git a/WINDOWS11_RAGFLOW_DEPLOYMENT_AND_MCP_GUIDE.md b/WINDOWS11_RAGFLOW_DEPLOYMENT_AND_MCP_GUIDE.md deleted file mode 100644 index 28c5d0a..0000000 --- a/WINDOWS11_RAGFLOW_DEPLOYMENT_AND_MCP_GUIDE.md +++ /dev/null @@ -1,1169 +0,0 @@ -# Windows 11 本地部署 RAGFlow 与 Cursor MCP 接入完整记录 - -这是一份按本次真实部署过程重新整理的操作文档。 - -我会尽量把每一步都写得温柔一点、清楚一点,让你以后自己回看时,不需要再从聊天记录里一点一点翻。 - -这份文档适用于: - -- Windows 11 -- Docker Desktop -- WSL2 -- PowerShell -- 本地通过 Docker 部署 RAGFlow -- 在 Cursor 中通过 MCP 访问本地知识库 - ---- - -## 1. 最终落地状态 - -本次实际部署目录: - -```powershell -D:\Project\ragflow -``` - -本次实际使用版本: - -```powershell -infiniflow/ragflow:v0.23.1 -``` - -本次实际对外端口如下: - -| 服务 | 主机端口 | 容器端口 | 说明 | -|---|---:|---:|---| -| RAGFlow Web UI | 38180 | 80 | 浏览器主入口 | -| RAGFlow HTTPS | 38443 | 443 | HTTPS 入口 | -| RAGFlow API | 39380 | 9380 | 主 API | -| RAGFlow Admin API | 39381 | 9381 | 管理端接口 | -| RAGFlow MCP | 39382 | 9382 | Cursor 连接的 MCP | -| Elasticsearch | 31200 | 9200 | 向量检索底层 | -| MySQL | 35455 | 3306 | 元数据数据库 | -| Redis | 36379 | 6379 | 缓存 | -| MinIO API | 39010 | 9000 | 对象存储 | -| MinIO Console | 39011 | 9001 | MinIO 控制台 | -| OpenSearch | 31201 | 9200 | 可选组件 | -| Kibana | 36601 | 5601 | 可选组件 | -| Infinity Thrift | 33817 | 23817 | 可选组件 | -| Infinity HTTP | 33820 | 23820 | 可选组件 | -| Infinity PostgreSQL | 35432 | 5432 | 可选组件 | -| OceanBase | 32881 | 2881 | 可选组件 | -| TEI | 36380 | 80 | 可选嵌入服务 | - -本次 Compose 项目名: - -```powershell -simeng-ragflow -``` - -因此容器名会类似: - -```powershell -simeng-ragflow-ragflow-cpu-1 -simeng-ragflow-mysql-1 -simeng-ragflow-minio-1 -``` - -这样做的好处是,容器、网络、卷都不会以默认的 `docker-` 前缀出现,更容易识别。 - ---- - -## 2. 这次实际改动过的关键文件 - -下面这些文件,是这次部署和修复里真正动过的: - -```powershell -D:\Project\ragflow\docker\.env -D:\Project\ragflow\docker\docker-compose.yml -D:\Project\ragflow\mcp\server\server.py -C:\Users\35016\.cursor\mcp.json -``` - -它们分别负责: - -- `docker\.env` - - 统一管理端口 - - 指定镜像版本 - - 指定 Compose 项目名 - - 配置 MCP 的 host、port、base URL、mode、host API key - -- `docker\docker-compose.yml` - - 让 `ragflow-cpu` 或 `ragflow-gpu` 真正带着 MCP 参数启动 - - 将主机上的 `mcp/server/server.py` 挂载到容器里 - -- `mcp\server\server.py` - - 修复空知识库导致 MCP 无限刷日志的问题 - -- `C:\Users\35016\.cursor\mcp.json` - - 把 Cursor 指向本机 `http://127.0.0.1:39382/mcp/` - ---- - -## 3. 为什么这次使用 v0.23.1 - -官方文档页面可能会展示更新的开发文档内容,但本次实际部署时,选择的是更稳妥的稳定版本: - -```powershell -infiniflow/ragflow:v0.23.1 -``` - -这样做的原因很简单: - -- 稳定版更适合本地长期使用 -- 与当前 Docker Compose 配置兼容性更稳定 -- 便于把问题范围收敛到部署和配置,而不是开发版变更 - -如果你后续要升级版本,建议先备份: - -- `docker\.env` -- `docker\docker-compose.yml` -- 自己修补过的 `mcp\server\server.py` - ---- - -## 4. Windows 11 上从零部署 RAGFlow 的完整步骤 - -### 4.1 准备环境 - -请先确认下面这些基础组件已经装好: - -- Windows 11 -- WSL2 -- Docker Desktop -- Git -- PowerShell 7 或 Windows PowerShell -- `curl.exe` - -可以先简单检查: - -```powershell -docker --version -docker compose version -git --version -wsl -l -v -curl.exe --version -``` - ---- - -### 4.2 创建部署目录 - -如果 `D:\Project` 不存在,先创建: - -```powershell -New-Item -ItemType Directory -Path 'D:\Project' -Force -``` - -进入目录并克隆官方仓库: - -```powershell -Set-Location 'D:\Project' -git clone https://github.com/infiniflow/ragflow.git -Set-Location 'D:\Project\ragflow' -``` - -如果已经有仓库目录,可以直接进入: - -```powershell -Set-Location 'D:\Project\ragflow' -``` - ---- - -### 4.3 设置 WSL 内核参数 `vm.max_map_count` - -这是 Elasticsearch 常见要求。如果不设置,RAGFlow 依赖的 ES 组件很容易启动失败。 - -本次实际使用的是临时设置方式: - -```powershell -wsl -d docker-desktop -u root -- sysctl -w vm.max_map_count=262144 -``` - -如果输出类似下面这样,就表示成功: - -```powershell -vm.max_map_count = 262144 -``` - -这一步非常重要。 - -如果 Docker Desktop 重启过,这个值有可能需要重新执行一次。 - ---- - -### 4.4 修改 `docker\.env` - -打开: - -```powershell -D:\Project\ragflow\docker\.env -``` - -本次实际关键配置如下: - -```dotenv -COMPOSE_PROJECT_NAME=simeng-ragflow - -ES_PORT=31200 -OS_PORT=31201 -KIBANA_PORT=36601 -INFINITY_THRIFT_PORT=33817 -INFINITY_HTTP_PORT=33820 -INFINITY_PSQL_PORT=35432 -OCEANBASE_PORT=32881 -MYSQL_PORT=35455 -MINIO_CONSOLE_PORT=39011 -MINIO_PORT=39010 -REDIS_PORT=36379 -SVR_WEB_HTTP_PORT=38180 -SVR_WEB_HTTPS_PORT=38443 -SVR_HTTP_PORT=39380 -ADMIN_SVR_HTTP_PORT=39381 -SVR_MCP_PORT=39382 -TEI_PORT=36380 - -RAGFLOW_MCP_HOST=0.0.0.0 -RAGFLOW_MCP_PORT=9382 -RAGFLOW_MCP_BASE_URL=http://127.0.0.1:9380 -RAGFLOW_MCP_MODE=self-host -RAGFLOW_MCP_HOST_API_KEY=ragflow-请替换为你自己的值 - -RAGFLOW_IMAGE=infiniflow/ragflow:v0.23.1 -TZ=Asia/Shanghai -``` - -请注意: - -- `RAGFLOW_MCP_BASE_URL` 这里写的是容器内 MCP 访问容器内 RAGFlow API 的地址,所以是 `http://127.0.0.1:9380` -- `SVR_MCP_PORT=39382` 是主机暴露出来给 Cursor 用的外部端口 -- `RAGFLOW_MCP_HOST_API_KEY` 不要直接公开写在文档、截图或聊天记录里 - -本机当前已经有一个可用的真实 key 存在于本地 `.env` 里。如果你是重新部署,请自行生成并填入。 - ---- - -### 4.5 修改 `docker\docker-compose.yml` - -打开: - -```powershell -D:\Project\ragflow\docker\docker-compose.yml -``` - -需要让 `ragflow-cpu` 或 `ragflow-gpu` 真正带着 MCP 参数启动。 - -本次 `ragflow-cpu` 实际结构如下: - -```yaml -ragflow-cpu: - depends_on: - mysql: - condition: service_healthy - profiles: - - cpu - image: ${RAGFLOW_IMAGE} - command: - - --enable-mcpserver - - --mcp-host=${RAGFLOW_MCP_HOST} - - --mcp-port=${RAGFLOW_MCP_PORT} - - --mcp-base-url=${RAGFLOW_MCP_BASE_URL} - - --mcp-script-path=/ragflow/mcp/server/server.py - - --mcp-mode=${RAGFLOW_MCP_MODE} - - --mcp-host-api-key=${RAGFLOW_MCP_HOST_API_KEY} - - --enable-adminserver - ports: - - ${SVR_WEB_HTTP_PORT}:80 - - ${SVR_WEB_HTTPS_PORT}:443 - - ${SVR_HTTP_PORT}:9380 - - ${ADMIN_SVR_HTTP_PORT}:9381 - - ${SVR_MCP_PORT}:9382 - volumes: - - ./ragflow-logs:/ragflow/logs - - ./nginx/ragflow.conf:/etc/nginx/conf.d/ragflow.conf - - ./nginx/proxy.conf:/etc/nginx/proxy.conf - - ./nginx/nginx.conf:/etc/nginx/nginx.conf - - ../history_data_agent:/ragflow/history_data_agent - - ../mcp/server/server.py:/ragflow/mcp/server/server.py - - ./service_conf.yaml.template:/ragflow/conf/service_conf.yaml.template - - ./entrypoint.sh:/ragflow/entrypoint.sh - env_file: .env - networks: - - ragflow - restart: unless-stopped - extra_hosts: - - "host.docker.internal:host-gateway" -``` - -如果你使用 GPU 版,也要把 `ragflow-gpu` 一起改掉,保持一致。 - -这里最重要的有三点: - -1. `--enable-mcpserver` - - 这是让 MCP 真正启动的开关 - -2. `--mcp-host-api-key=${RAGFLOW_MCP_HOST_API_KEY}` - - 这是给容器内 MCP 进程访问 RAGFlow API 用的,不是给 Cursor 客户端用的 - -3. `- ../mcp/server/server.py:/ragflow/mcp/server/server.py` - - 这是为了让本地修补过的 `server.py` 真正进入容器 - ---- - -### 4.6 启动服务 - -进入 `docker` 目录: - -```powershell -Set-Location 'D:\Project\ragflow\docker' -``` - -首次启动: - -```powershell -docker compose up -d -``` - -查看状态: - -```powershell -docker compose ps -``` - -也可以直接看全局容器: - -```powershell -docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" -``` - -本次正常容器应至少包括: - -```powershell -simeng-ragflow-ragflow-cpu-1 -simeng-ragflow-mysql-1 -simeng-ragflow-minio-1 -simeng-ragflow-redis-1 -simeng-ragflow-es01-1 -``` - ---- - -## 5. 首次启动后的验证 - -### 5.1 检查 Web UI - -浏览器访问: - -```powershell -http://127.0.0.1:38180 -``` - -如果能打开前端页面,说明 Web 层已经起来了。 - ---- - -### 5.2 检查健康接口 - -运行: - -```powershell -curl.exe -s --noproxy "*" http://127.0.0.1:39380/v1/system/healthz -``` - -本次正常返回示例: - -```json -{"db":"ok","doc_engine":"ok","redis":"ok","status":"ok","storage":"ok"} -``` - -只要这里全部是 `ok`,就说明主链路正常。 - ---- - -## 6. 默认账号与登录说明 - -RAGFlow 默认管理员账号来自官方文档: - -```text -admin@ragflow.io -admin -``` - -访问地址: - -```powershell -http://127.0.0.1:38180/admin -``` - -请特别注意: - -- 这个默认管理员账号只能登录 `/admin` -- 不能登录普通前台 -- 如果你拿它去登录普通前台,会收到类似: - -```text -Default admin account cannot be used to login normal services! -``` - -这不是密码错,而是 RAGFlow 本身就这样设计。 - -普通使用方式是: - -- 管理后台:`/admin` -- 普通用户前台:`/` -- 普通用户需要注册新账号,或者由管理员创建 - ---- - -## 7. 这次实际遇到的问题与解决方案 - -这一节很重要,因为这里不是“理论问题”,而是这次在 Windows 11 本机部署时真实踩到的坑。 - -### 7.1 问题一:MinIO 缺少 bucket,健康检查返回 500 - -#### 现象 - -初次启动后,RAGFlow 的健康检查可能失败,日志里会出现类似 `NoSuchBucket`,接口返回 500。 - -#### 根因 - -MinIO 服务起来了,但 `ragflow-bucket` 没有自动建立。 - -#### 解决方案 - -进入一个能运行 Python 的 RAGFlow 容器,手工创建 bucket: - -```powershell -docker exec simeng-ragflow-ragflow-cpu-1 python -c "from minio import Minio; c=Minio('minio:9000', access_key='rag_flow', secret_key='infini_rag_flow', secure=False); b='ragflow-bucket'; print('exists_before=' + str(c.bucket_exists(b))); (None if c.bucket_exists(b) else c.make_bucket(b)); print('exists_after=' + str(c.bucket_exists(b)))" -``` - -创建成功后,再次检查: - -```powershell -curl.exe -s --noproxy "*" http://127.0.0.1:39380/v1/system/healthz -``` - -如果返回全 `ok`,说明已经恢复正常。 - ---- - -### 7.2 问题二:MCP 端口明明映射了,但 Cursor 还是连不上 - -#### 现象 - -宿主机上看到已经有: - -```powershell -39382 -> 9382 -``` - -但 Cursor 仍然不可用,或者访问时表现异常。 - -#### 根因 - -仅仅暴露端口并不等于 MCP 真的启动了。 - -之前的问题就是: - -- Docker 做了 `39382 -> 9382` 的端口映射 -- 但容器内其实没有 MCP 进程监听 `9382` - -所以表现会像: - -- `/sse` 访问空响应 -- 或容器里 `127.0.0.1:9382` 直接 `Connection refused` - -#### 解决方案 - -必须在 `docker-compose.yml` 里显式增加: - -```yaml -command: - - --enable-mcpserver - - --mcp-host=${RAGFLOW_MCP_HOST} - - --mcp-port=${RAGFLOW_MCP_PORT} - - --mcp-base-url=${RAGFLOW_MCP_BASE_URL} - - --mcp-script-path=/ragflow/mcp/server/server.py - - --mcp-mode=${RAGFLOW_MCP_MODE} - - --mcp-host-api-key=${RAGFLOW_MCP_HOST_API_KEY} -``` - -然后重建容器: - -```powershell -Set-Location 'D:\Project\ragflow\docker' -docker compose up -d --force-recreate ragflow-cpu -``` - ---- - -### 7.3 问题三:Cursor 配置写成 `/mcp`,实际应该写 `/mcp/` - -#### 现象 - -MCP 有时看起来能通,有时又初始化失败,行为不稳定。 - -#### 根因 - -`/mcp` 会发生 `307` 重定向到 `/mcp/`。 - -有些 MCP 客户端对这个跳转处理得不够稳定,所以最好直接写最终地址。 - -#### 解决方案 - -Cursor 配置使用: - -```json -{ - "mcpServers": { - "RAGFlow": { - "url": "http://127.0.0.1:39382/mcp/" - } - } -} -``` - -不要写成: - -```json -{ - "mcpServers": { - "RAGFlow": { - "url": "http://127.0.0.1:39382/mcp" - } - } -} -``` - ---- - -### 7.4 问题四:MCP 查询一发起,容器日志疯狂刷屏 - -#### 现象 - -在容器 `simeng-ragflow-ragflow-cpu-1` 中,MCP 发起检索后,日志不断重复请求: - -```text -/api/v1/datasets//documents?page=1 -``` - -几乎像死循环一样不停输出。 - -#### 本次触发问题的请求示例 - -```json -{ - "question": "vuepress-theme-plume 博客文章 frontmatter tags 标签配置", - "page_size": 8, - "similarity_threshold": 0.2 -} -``` - -#### 根因 - -`mcp/server/server.py` 中有一段逻辑会在补齐 `document_metadata` 时遍历知识库文档分页。 - -如果某个知识库是空的,也就是: - -```text -docs = [] -``` - -原来的代码既没有翻页,也没有退出循环,于是它会一直打同一个: - -```text -/documents?page=1 -``` - -这次实际触发该问题的原因是: - -- 查询时没有传 `dataset_ids` -- MCP 会自动遍历所有可用知识库 -- 其中正好包含一个空知识库 -- 空知识库触发了分页死循环 - -#### 修复方式 - -已在: - -```powershell -D:\Project\ragflow\mcp\server\server.py -``` - -中补上保护逻辑。核心思路是: - -- 请求失败就退出 -- `docs` 为空就退出 -- `code != 0` 就退出 -- 当 `page * page_size >= total` 时退出 - -本次修补后的关键逻辑可以概括为: - -```python -docs_res = self._get(f"/datasets/{dataset_id}/documents", {"page": page, "page_size": page_size}) -if not docs_res or docs_res.status_code != 200: - break - -docs_data = docs_res.json() -page_docs = docs_data.get("data", {}).get("docs") or [] -total = docs_data.get("data", {}).get("total", 0) or 0 - -if docs_data.get("code") != 0 or not page_docs: - break - -if page * page_size >= total: - break -``` - -#### 为什么还要挂载 `server.py` - -因为容器内部默认使用镜像里自带的 `server.py`。 - -如果你只是改了主机文件,但没有在 Compose 里加: - -```yaml -- ../mcp/server/server.py:/ragflow/mcp/server/server.py -``` - -那容器里运行的仍然是旧代码,问题不会真正消失。 - ---- - -### 7.5 问题五:PowerShell 里发中文 JSON,MCP 返回 `utf-8 decode` 错误 - -#### 现象 - -通过 PowerShell 把中文问题写进 JSON,再用 `curl` 提交时,MCP 返回类似编码错误。 - -#### 根因 - -Windows 下某些写文件方式默认带 BOM,或者不是严格的 UTF-8 无 BOM,服务端解析时会异常。 - -#### 解决方案 - -用 UTF-8 无 BOM 明确写文件: - -```powershell -$tmp = Join-Path $env:TEMP 'ragflow_mcp_test.json' -$body = '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ragflow_retrieval","arguments":{"question":"vuepress-theme-plume 博客文章 frontmatter tags 标签配置","page_size":8,"similarity_threshold":0.2}}}' -$utf8NoBom = New-Object System.Text.UTF8Encoding($false) -[System.IO.File]::WriteAllText($tmp, $body, $utf8NoBom) -``` - -然后再请求: - -```powershell -curl.exe -s --noproxy "*" -H "Accept: application/json, text/event-stream" -H "Content-Type: application/json" --data-binary "@$tmp" http://127.0.0.1:39382/mcp/ -``` - ---- - -### 7.6 问题六:刚重建容器后,MCP 短时间内 `Connection refused` - -#### 现象 - -你刚执行完重建,立刻测试 `/mcp/` 或 `/sse`,可能会看到连接失败。 - -#### 根因 - -MCP 进程已经在起,但主 API `9380` 还没完全 ready,服务存在启动顺序窗口期。 - -#### 解决方案 - -先等健康检查恢复为 `ok`,再测: - -```powershell -curl.exe -s --noproxy "*" http://127.0.0.1:39380/v1/system/healthz -``` - -只要主 API 健康了,再去测 MCP,通常就会稳定。 - ---- - -### 7.7 问题七:MCP 能连上,但检索报 Ollama 连接错误 - -#### 现象 - -MCP 初始化正常,但真正执行检索或召回时,返回类似: - -```text -Failed to connect to Ollama. Please check that Ollama is downloaded, running and accessible. -``` - -#### 根因 - -这通常不是 MCP 网络层的问题,而是 RAGFlow 当前所绑定的模型服务不可用。 - -也就是说: - -- MCP 通了 -- RAGFlow 主服务也通了 -- 但 RAGFlow 检索链路依赖的模型服务没有通 - -#### 解决方案 - -检查你在 RAGFlow 后台配置的模型是否真的可用: - -- 如果使用 Ollama,确认 Ollama 进程在运行 -- 如果使用 OpenAI 兼容接口,确认 API 地址和 key 正确 -- 如果使用本地代理,确认代理服务本身是正常的 - -这个问题和 “Cursor 的 MCP 配置” 不是同一层,排障时不要混在一起看。 - ---- - -## 8. 如何配置 MCP - -这一节分成两部分: - -- RAGFlow 服务端如何启用 MCP -- Cursor 客户端如何接入 MCP - ---- - -### 8.1 服务端 MCP 配置 - -服务端的关键不在 Cursor,而在 RAGFlow 的容器启动参数。 - -#### `.env` 中的 MCP 相关配置 - -```dotenv -RAGFLOW_MCP_HOST=0.0.0.0 -RAGFLOW_MCP_PORT=9382 -RAGFLOW_MCP_BASE_URL=http://127.0.0.1:9380 -RAGFLOW_MCP_MODE=self-host -RAGFLOW_MCP_HOST_API_KEY=ragflow-请替换为你自己的值 -``` - -#### `docker-compose.yml` 中必须有的参数 - -```yaml -command: - - --enable-mcpserver - - --mcp-host=${RAGFLOW_MCP_HOST} - - --mcp-port=${RAGFLOW_MCP_PORT} - - --mcp-base-url=${RAGFLOW_MCP_BASE_URL} - - --mcp-script-path=/ragflow/mcp/server/server.py - - --mcp-mode=${RAGFLOW_MCP_MODE} - - --mcp-host-api-key=${RAGFLOW_MCP_HOST_API_KEY} -``` - -这里最容易混淆的一点是: - -- `RAGFLOW_MCP_HOST_API_KEY` 是给服务端 MCP 自己去访问 RAGFlow API 用的 -- 不是说 Cursor 一定要把这个 key 带出去 - -本次实际验证下,Cursor 侧可以不配置 API key,仍可通过 `http://127.0.0.1:39382/mcp/` 正常工作。 - ---- - -### 8.2 Cursor 侧 MCP 配置 - -Cursor 全局配置文件位置: - -```powershell -C:\Users\35016\.cursor\mcp.json -``` - -本次最终可用配置如下: - -```json -{ - "mcpServers": { - "RAGFlow": { - "url": "http://127.0.0.1:39382/mcp/" - } - } -} -``` - -请注意两个细节: - -1. 使用 `127.0.0.1`,不要混用 `localhost` -2. 使用 `/mcp/`,不要写成 `/mcp` - -如果你已经改好配置,但 Cursor 面板没有刷新出来,可以: - -- 重启 Cursor -- 或重新打开 MCP 面板 - ---- - -## 9. 如何验证 MCP 是否正常 - -这一节给出的是 Windows 11 下可以直接运行的 PowerShell 命令。 - ---- - -### 9.1 验证 `/sse` - -```powershell -curl.exe -i --max-time 3 --noproxy "*" http://127.0.0.1:39382/sse -``` - -正常时会看到类似: - -```text -HTTP/1.1 200 OK -content-type: text/event-stream; charset=utf-8 - -event: endpoint -data: /messages/?session_id=xxxx -``` - -这里超时是正常的,因为 SSE 本来就是长连接。 - -只要能看到 `HTTP/1.1 200 OK` 和 `event: endpoint`,就说明监听已经在了。 - ---- - -### 9.2 验证 `/mcp/ initialize` - -```powershell -$tmp = Join-Path $env:TEMP 'ragflow_mcp_init.json' -$body = '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"local-test","version":"1.0.0"}}}' -$utf8NoBom = New-Object System.Text.UTF8Encoding($false) -[System.IO.File]::WriteAllText($tmp, $body, $utf8NoBom) - -curl.exe -s -i --noproxy "*" ` - -H "Accept: application/json, text/event-stream" ` - -H "Content-Type: application/json" ` - --data-binary "@$tmp" ` - http://127.0.0.1:39382/mcp/ -``` - -正常时会返回 `200 OK`,并带上 `serverInfo`。 - ---- - -### 9.3 验证 `tools/list` - -```powershell -$tmp = Join-Path $env:TEMP 'ragflow_mcp_tools_list.json' -$body = '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' -$utf8NoBom = New-Object System.Text.UTF8Encoding($false) -[System.IO.File]::WriteAllText($tmp, $body, $utf8NoBom) - -curl.exe -s --noproxy "*" ` - -H "Accept: application/json, text/event-stream" ` - -H "Content-Type: application/json" ` - --data-binary "@$tmp" ` - http://127.0.0.1:39382/mcp/ -``` - -正常时你会看到 `ragflow_retrieval` 这个工具,以及当前可用知识库列表。 - ---- - -### 9.4 验证 `tools/call` - -```powershell -$tmp = Join-Path $env:TEMP 'ragflow_mcp_tool_call.json' -$body = '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"ragflow_retrieval","arguments":{"question":"vuepress-theme-plume 博客文章 frontmatter tags 标签配置","page_size":8,"similarity_threshold":0.2}}}' -$utf8NoBom = New-Object System.Text.UTF8Encoding($false) -[System.IO.File]::WriteAllText($tmp, $body, $utf8NoBom) - -curl.exe -s --noproxy "*" ` - -H "Accept: application/json, text/event-stream" ` - -H "Content-Type: application/json" ` - --data-binary "@$tmp" ` - http://127.0.0.1:39382/mcp/ -``` - -如果返回真正的 chunk 内容,说明 MCP 与知识库已经打通。 - -如果返回模型错误,而不是网络错误,说明: - -- MCP 已通 -- 但 RAGFlow 内部模型服务仍需单独检查 - ---- - -## 10. 本次 MCP 疯狂刷日志的修复记录 - -为了方便以后回看,这里单独整理一下这次最关键的故障。 - -### 问题表现 - -容器: - -```powershell -simeng-ragflow-ragflow-cpu-1 -``` - -在接到 MCP 检索请求后,日志不断刷: - -```text -GET /api/v1/datasets//documents?page=1 -``` - -### 问题原因 - -MCP 在查询时,如果没有传 `dataset_ids`,会遍历全部知识库。 - -其中只要有一个空知识库,就可能进入原逻辑的死循环。 - -### 修复文件 - -```powershell -D:\Project\ragflow\mcp\server\server.py -``` - -### 修复要点 - -- 当 `/documents` 返回空列表时,立即退出分页 -- 当状态码非 200 时退出 -- 当接口 `code != 0` 时退出 -- 按 `total` 正确结束分页 - -### 为什么这一步非常关键 - -如果不修,表面上看是 “日志太多”,但本质上会带来: - -- 不必要的 API 压力 -- Cursor 端响应变慢 -- 排障时非常容易误判成网络问题或死锁问题 - ---- - -## 11. RAGFlow 日常启动、停止、重建命令 - -### 启动前先设置内核参数 - -```powershell -wsl -d docker-desktop -u root -- sysctl -w vm.max_map_count=262144 -``` - -### 启动 - -```powershell -Set-Location 'D:\Project\ragflow\docker' -docker compose up -d -``` - -### 停止 - -```powershell -Set-Location 'D:\Project\ragflow\docker' -docker compose down -``` - -### 只重建 RAGFlow 主容器 - -```powershell -Set-Location 'D:\Project\ragflow\docker' -docker compose up -d --force-recreate ragflow-cpu -``` - -### 查看日志 - -```powershell -docker logs --tail 200 simeng-ragflow-ragflow-cpu-1 -``` - -持续跟踪: - -```powershell -docker logs -f simeng-ragflow-ragflow-cpu-1 -``` - -### 查看容器 - -```powershell -docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" -``` - ---- - -## 12. 不建议直接做的事情 - -### 12.1 不要轻易执行 `docker compose down -v` - -这个命令会把卷一起删掉。 - -如果你没有明确打算重置数据,尽量不要这样做。 - -推荐只用: - -```powershell -docker compose down -``` - ---- - -### 12.2 不要把默认管理员密码长期保留在对外环境中 - -默认管理员账号只适合本地测试。 - -如果要用于局域网或公网,建议尽快处理: - -- 修改管理员密码 -- 关闭不必要的注册入口 -- 修改 `.env` 中的默认弱口令 - ---- - -### 12.3 不要把真实的 MCP host API key 写进文档或发给别人 - -这类 key 应只保存在: - -- 本地 `.env` -- 安全的密码管理工具 - -这份文档里只保留占位符,是为了避免后续二次泄露。 - ---- - -## 13. 推荐的排障顺序 - -如果以后再出现问题,建议按这个顺序排: - -1. 先看容器在不在 - -```powershell -docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" -``` - -2. 再看主服务健康不健康 - -```powershell -curl.exe -s --noproxy "*" http://127.0.0.1:39380/v1/system/healthz -``` - -3. 再看 MCP 端口是否在监听 - -```powershell -curl.exe -i --max-time 3 --noproxy "*" http://127.0.0.1:39382/sse -``` - -4. 再测 `/mcp/` 初始化 - -5. 最后才去看 Cursor 配置 - -这样排会比较稳,不容易把“模型问题”“服务问题”“客户端配置问题”混在一起。 - ---- - -## 14. 一份最小可用检查清单 - -如果你只想快速确认现在能不能用,可以看这一小节。 - -### RAGFlow 是否正常 - -- [ ] `http://127.0.0.1:38180` 能打开 -- [ ] `http://127.0.0.1:38180/admin` 能打开 -- [ ] `http://127.0.0.1:39380/v1/system/healthz` 返回全 `ok` - -### MCP 是否正常 - -- [ ] `http://127.0.0.1:39382/sse` 能返回 `event: endpoint` -- [ ] `initialize` 返回 `200` -- [ ] `tools/list` 能列出 `ragflow_retrieval` -- [ ] `tools/call` 能返回知识库内容,或者至少返回模型层错误而不是网络层错误 - -### Cursor 是否配置正确 - -- [ ] `C:\Users\35016\.cursor\mcp.json` 已写入 `http://127.0.0.1:39382/mcp/` -- [ ] 地址使用了 `/mcp/` -- [ ] 改完后已重启 Cursor - ---- - -## 15. 本次部署中可直接参考的文件路径总表 - -### 部署目录 - -```powershell -D:\Project\ragflow -``` - -### 环境变量 - -```powershell -D:\Project\ragflow\docker\.env -``` - -### Compose 文件 - -```powershell -D:\Project\ragflow\docker\docker-compose.yml -``` - -### MCP 服务端实现 - -```powershell -D:\Project\ragflow\mcp\server\server.py -``` - -### Cursor MCP 配置 - -```powershell -C:\Users\35016\.cursor\mcp.json -``` - -### 官方管理员文档 - -```powershell -D:\Project\ragflow\docs\guides\accessing_admin_ui.md -``` - -### 普通登录限制代码 - -```powershell -D:\Project\ragflow\api\apps\user_app.py -``` - ---- - -## 16. 一点温柔的提醒 - -这套链路表面上看只是 “把 RAGFlow 跑起来,再在 Cursor 里配个 MCP”。 - -但实际踩下来,你会发现它至少包含四层: - -- Docker 层 -- RAGFlow 服务层 -- MCP 服务层 -- Cursor 客户端层 - -任何一层不通,都会表现成 “好像 MCP 有问题”。 - -所以以后遇到异常时,别急,也别怀疑自己哪里全都弄错了。 - -多数时候只是某一层状态没有对齐。 - -按这份文档一层一层检查,通常就能很快找到问题点。 - ---- - -## 17. 参考链接 - -- 官方文档: -- 官方仓库: -- 官方 Releases: - ---- - -## 18. 本次文档重建说明 - -这份文档是根据本次实际部署、修复、验证过程重新整理的。 - -它特别保留了这次真实发生过的关键问题: - -- MinIO bucket 缺失 -- 默认管理员账号不能登录普通前台 -- MCP 端口映射了但实际没有启动 -- Cursor `/mcp` 与 `/mcp/` 的差异 -- 空知识库导致 MCP 日志无限刷屏 -- PowerShell 中文 JSON 编码问题 -- 模型服务异常与 MCP 异常的区分 - -如果以后你继续调整: - -- 模型配置 -- Docker 端口 -- MCP 参数 -- `server.py` 修补逻辑 - -建议同步更新这份文档,这样后面你自己维护会轻松很多。 diff --git a/docs/.vuepress/collections.ts b/docs/.vuepress/collections.ts index d5c5b8a..2157828 100644 --- a/docs/.vuepress/collections.ts +++ b/docs/.vuepress/collections.ts @@ -36,6 +36,13 @@ export default defineCollections([ linkPrefix: '/ai/', sidebar: [ { text: '模型', link: '/ai/' }, + { + text: '基础概念', + collapsed: false, + items: [ + { text: 'MCP 与 Skills 详解', link: '/article/mcp-and-skills/' }, + ], + }, { text: '部署与工具链', collapsed: false, diff --git a/docs/notes/ai/mcp-and-skills.md b/docs/notes/ai/mcp-and-skills.md new file mode 100644 index 0000000..87a4314 --- /dev/null +++ b/docs/notes/ai/mcp-and-skills.md @@ -0,0 +1,188 @@ +--- +title: MCP 与 Skills:让 AI 助手更懂你的利器 +createTime: 2026/03/29 14:00:00 +permalink: /article/mcp-and-skills/ +sidebar: '/ai/' +--- + +嗨~今天来聊聊两个让 AI 助手变得更聪明、更贴心的小魔法:**MCP** 和 **Skills** 🪄 + +它们就像是给 AI 装上了「外挂」和「说明书」,让它不仅能聊天,还能真正帮你干活、调用工具、甚至访问你的本地知识库~ + + +## 一、MCP 是什么? + +**MCP** 全称是 **Model Context Protocol**(模型上下文协议),是由 [Anthropic](https://www.anthropic.com/) 提出的一种开放协议。 + +简单来说,它就像是 AI 和外部世界之间的「通用翻译官」🌐 + +### 为什么需要 MCP? + +想象一下: +- 你想让 AI 查一下你的本地数据库 +- 你想让 AI 调用某个特定工具 +- 你想让 AI 访问你的笔记知识库 + +以前,每个工具都要写一套单独的对接代码,很麻烦对吧? + +MCP 的出现,就是为了让这些「对接」变得标准化——**一次配置,到处可用**。 + +### MCP 的工作原理 + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ AI 助手 │ ◄──► │ MCP 协议 │ ◄──► │ 外部工具 │ +│ (Cursor等) │ │ (标准化) │ │ (数据库/API) │ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +AI 助手通过 MCP 协议,可以: +- 🔍 **检索**(Retrieval):查询知识库、数据库 +- 🛠️ **调用工具**(Tools):执行特定功能 +- 💾 **访问资源**(Resources):读取文件、配置等 + + +## 二、Skills 是什么? + +如果说 MCP 是「通信协议」,那 **Skills** 就是「技能说明书」📖 + +### Skills 的概念 + +Skills(技能)是封装好的、可复用的功能模块。每个 Skill 通常包含: +- **功能描述**:这个技能是干嘛的 +- **调用方式**:需要哪些参数、返回什么结果 +- **使用示例**:实际怎么调用 + +### MCP vs Skills 的关系 + +| 概念 | 比喻 | 作用 | +|------|------|------| +| **MCP** | 电话线/网络协议 📡 | 负责「能连上」 | +| **Skills** | 电话簿/功能菜单 📋 | 负责「知道能做什么」 | + +MCP 让 AI 和工具**连得通**,Skills 让 AI**知道怎么用**。 + + +## 三、实际应用场景 + +### 场景 1:本地知识库检索 🗃️ + +就像我在 [RAGFlow 部署文章](../windows11-ragflow-deployment-mcp/) 里写的,通过 MCP 把 RAGFlow 接到 Cursor 里: + +```json +// Cursor 的 MCP 配置 +{ + "mcpServers": { + "RAGFlow": { + "url": "http://127.0.0.1:39382/mcp/" + } + } +} +``` + +然后 AI 就能: +- 自动检索你的笔记 +- 基于本地知识回答问题 +- 不用把敏感文件上传到云端 + +### 场景 2:数据库查询 🗄️ + +配置一个数据库 MCP Server,AI 就能直接帮你: + +``` +用户:查一下上个月销售额最高的产品 +AI:【通过 MCP 调用数据库查询工具】 + SELECT product_name, SUM(sales) + FROM sales + WHERE date >= '2025-02-01' + GROUP BY product_name + ORDER BY SUM(sales) DESC + LIMIT 1; + + 结果是:产品 A,销售额 ¥123,456 +``` + +### 场景 3:文件操作 📁 + +通过文件系统 MCP,AI 可以: +- 读取项目配置文件 +- 批量重命名文件 +- 生成代码并保存到指定目录 + + +## 四、在 Cursor 中使用 + +### 配置 MCP Server + +以 Cursor 为例,在 `~/.cursor/mcp.json` 中添加: + +```json +{ + "mcpServers": { + "my-database": { + "url": "http://localhost:3000/mcp" + }, + "file-system": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"] + } + } +} +``` + +### 使用流程 + +1. **AI 发现技能**:启动时,AI 会自动获取所有可用的 Skills 列表 +2. **意图识别**:当你提问时,AI 判断是否需要调用工具 +3. **参数填充**:AI 自动提取所需参数 +4. **执行并返回**:调用 MCP Server,获取结果后呈现给你 + +### 交互示例 + +``` +你:帮我总结一下项目里的 API 接口 + +AI:我来帮你分析一下项目中的 API 接口。 + 【调用 file-system skill 读取项目文件】 + 【调用检索 skill 查找路由定义】 + + 找到以下接口: + 1. GET /api/users - 获取用户列表 + 2. POST /api/users - 创建用户 + 3. GET /api/users/:id - 获取单个用户 + ... +``` + + +## 五、MCP 生态一览 + +目前 MCP 生态正在快速发展,已有许多现成的 Server 可用: + +| 类型 | 代表项目 | 用途 | +|------|---------|------| +| 文件系统 | `@modelcontextprotocol/server-filesystem` | 读写本地文件 | +| 数据库 | `@modelcontextprotocol/server-postgres` | PostgreSQL 查询 | +| GitHub | `@modelcontextprotocol/server-github` | 操作 GitHub | +| 浏览器 | `@browserbasehq/mcp-server-browserbase` | 自动化浏览器操作 | +| 知识库 | RAGFlow MCP | 本地文档检索 | + +完整的官方列表可以在 [MCP Servers Repository](https://github.com/modelcontextprotocol/servers) 找到。 + + +## 六、总结 + +| 要点 | 说明 | +|------|------| +| **MCP** | 让 AI 和工具「说同一种语言」的开放协议 | +| **Skills** | 封装好的功能模块,告诉 AI「我能做什么」 | +| **价值** | 打破信息孤岛,让 AI 真正连接你的数字世界 | +| **前景** | 越来越多的工具会支持 MCP,生态会越来越丰富 | + +用一句话概括:**MCP 是桥梁,Skills 是地图,让 AI 从「聊天伙伴」变成「得力助手」** 🎯 + +--- + +> 💡 **延伸阅读** +> - [Windows 11 本地部署 RAGFlow 与 Cursor MCP](./windows11-ragflow-deployment-mcp.md) +> - [MCP 官方文档](https://modelcontextprotocol.io/) +> - [Anthropic MCP 介绍](https://www.anthropic.com/news/model-context-protocol)