企业内网本地 LLM + MCP 工具链试点落地指南

1. 改写后的明确需求

将原请求改写为:

> 基于 XDA 文章中“本地 LLM 通过 MCP 接入搜索、文档、记忆、网页抓取和浏览器自动化”的经验,提炼一份适合企业内网小范围试点的落地技术文档。文档需要包含最小架构、部署步骤、样例配置、3 个以上可执行场景、安全边界、验收标准、失败处理和 4 周推广计划。

改写点:

2. 一句话结论

企业内网落地本地 LLM + MCP,不应先追求全自动智能体,而应先建设一套“小模型 + 少量高频 MCP 工具 + 只读数据源 + 人工确认 + 审计日志”的低风险试点环境,用 3–5 个内部场景验证价值后再扩展权限。

3. 试点边界

3.1 第一阶段目标

3.2 第一阶段不做什么

4. 最小可行架构

员工 / 研发 / 运维
  │
  ├─ Web UI / CLI / IDE 插件
  │
  ▼
内网 LLM 客户端
  - OpenAI-compatible API client
  - MCP client
  - 工具白名单
  - 会话日志脱敏
  │
  ├─ 本地/内网推理服务
  │    - Ollama / vLLM / LM Studio / 企业统一推理网关
  │    - 按场景选择模型
  │
  ├─ MCP Server 层
  │    - SearXNG:内网/公开资料搜索
  │    - Context7 或内部文档 MCP:技术文档查询
  │    - Qdrant:向量检索
  │    - OpenMemory/mem0:对话事实记忆
  │    - Crawl4AI:网页正文抓取
  │    - Playwright:需要登录/点击/分页的浏览器操作
  │
  ├─ 受控数据目录
  │    - data/policies/
  │    - data/runbooks/
  │    - data/code_samples/
  │    - data/incidents/
  │
  └─ 输出与审计
       - outputs/
       - logs/redacted_sessions/
       - audit/tool_calls.jsonl

5. 推荐组件清单

| 能力 | 推荐组件 | 企业内网用途 | 第一阶段权限 | |---|---|---|---| | 模型推理 | Ollama / vLLM / OpenAI-compatible gateway | 提供统一模型接口 | 仅内网访问 | | 搜索 | SearXNG MCP | 搜索内部知识库、公开资料镜像 | 只读 | | 最新技术文档 | Context7 或内部文档 MCP | 查询框架/API 文档 | 只读 | | 向量库 | Qdrant | 文档、代码片段、故障案例语义检索 | 只读检索,受控导入 | | 记忆层 | OpenMemory/mem0 | 保存用户偏好、团队上下文、环境事实 | 低敏事实,人工可清理 | | 网页抓取 | Crawl4AI MCP | 把网页转成 Markdown | 只读 | | 浏览器自动化 | Playwright MCP | 登录内网页面、翻页、导出报告 | 测试账号,只读 |

> 注意:Context7 默认依赖外部托管文档库;如果内网不允许访问外部服务,应替换为内部文档 MCP 或把官方文档离线镜像后导入向量库。

6. 目录结构建议

intranet-llm-mcp-pilot/
├── README.md
├── .env.example
├── docker-compose.yml
├── config/
│   ├── mcp.servers.json
│   ├── model-routing.yaml
│   └── security-policy.yaml
├── data/
│   ├── policies/
│   ├── runbooks/
│   ├── code_samples/
│   └── incidents/
├── scripts/
│   ├── ingest_docs.py
│   ├── run_readonly_agent.py
│   └── redact_logs.py
├── outputs/
└── audit/
    └── tool_calls.jsonl

7. 基础部署步骤

7.1 准备 .env

cp .env.example .env

.env.example

LLM_BASE_URL=http://127.0.0.1:11434/v1
LLM_API_KEY=local-not-required
LLM_MODEL=qwen2.5:14b-instruct
QDRANT_URL=http://127.0.0.1:6333
SEARXNG_URL=http://127.0.0.1:8080
AUDIT_LOG=./audit/tool_calls.jsonl
OUTPUT_DIR=./outputs
DATA_ROOT=./data

要求:

7.2 启动基础服务

docker-compose.yml 示例:

services:
  qdrant:
    image: qdrant/qdrant:latest
    ports:
      - "127.0.0.1:6333:6333"
    volumes:
      - ./qdrant_storage:/qdrant/storage

  searxng:
    image: searxng/searxng:latest
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./searxng:/etc/searxng

  crawl4ai:
    image: unclecode/crawl4ai:latest
    ports:
      - "127.0.0.1:11235:11235"

启动:

docker compose up -d
curl http://127.0.0.1:6333/collections
curl http://127.0.0.1:8080
curl http://127.0.0.1:11235/health

验收标准:

失败处理:

7.3 配置 MCP Server 白名单

config/mcp.servers.json 示例:

{
  "servers": {
    "search": {
      "command": "python",
      "args": ["-m", "mcp_searxng"],
      "env": {
        "SEARXNG_URL": "http://127.0.0.1:8080"
      }
    },
    "crawl4ai": {
      "command": "python",
      "args": ["-m", "mcp_crawl4ai"],
      "env": {
        "CRAWL4AI_URL": "http://127.0.0.1:11235"
      }
    },
    "qdrant_readonly": {
      "command": "python",
      "args": ["-m", "mcp_qdrant_readonly"],
      "env": {
        "QDRANT_URL": "http://127.0.0.1:6333"
      }
    }
  },
  "policy": {
    "default": "deny",
    "allowed_tools": [
      "search.query",
      "crawl4ai.fetch_markdown",
      "qdrant_readonly.search"
    ],
    "blocked_tools": [
      "shell.run",
      "database.write",
      "kubernetes.delete",
      "email.send"
    ]
  }
}

验收标准:

8. 场景一:企业制度 / 运维手册问答

8.1 目标

让模型基于内网制度、运维手册、故障复盘文档回答问题,并返回引用来源。

8.2 样例文件

data/policies/change_policy.md

# 变更管理制度

- 生产变更必须提前 1 个工作日提交审批。
- 数据库 DDL 必须提供回滚方案。
- 高峰期禁止执行高风险变更。
- 紧急变更必须在 24 小时内补充复盘。

data/runbooks/postgres_lock_runbook.md

# PostgreSQL 锁等待处理手册

1. 查询锁等待会话。
2. 联系业务确认影响范围。
3. 禁止直接 kill 生产会话,除非获得 DBA 确认。
4. 处理完成后记录 SQL、时间、影响表和审批人。

8.3 导入向量库

scripts/ingest_docs.py 示例逻辑:

from pathlib import Path

DATA_ROOT = Path("data")

for path in DATA_ROOT.rglob("*.md"):
    text = path.read_text(encoding="utf-8")
    print({
        "path": str(path),
        "chars": len(text),
        "collection": "internal_docs"
    })
    # 实际项目中:分块、生成 embedding、写入 Qdrant

运行:

python scripts/ingest_docs.py

8.4 测试问题

如果我需要在生产库执行 DDL,需要准备什么?

期望输出形态:

结论:生产 DDL 至少需要提前审批、回滚方案和风险窗口确认。
依据:
- data/policies/change_policy.md:数据库 DDL 必须提供回滚方案。
- data/policies/change_policy.md:生产变更必须提前 1 个工作日提交审批。
注意:如果是紧急变更,需 24 小时内补充复盘。

验收标准:

失败处理:

9. 场景二:本地代码审查助手

9.1 目标

让模型对代码样例做只读审查,输出风险点、证据行、修改建议,不直接改代码。

9.2 样例代码

data/code_samples/user_api.py

import sqlite3


def get_user(user_id):
    conn = sqlite3.connect("users.db")
    sql = f"SELECT * FROM users WHERE id = {user_id}"
    return conn.execute(sql).fetchone()

9.3 审查提示词

你是企业内部代码审查助手。请只读审查下面代码:
1. 找出安全、可靠性、可维护性问题。
2. 每个问题必须指出证据行或代码片段。
3. 给出最小修改建议。
4. 不要直接写文件,不要执行命令。

9.4 期望输出形态

风险等级:高
问题 1:SQL 注入风险
证据:f"SELECT * FROM users WHERE id = {user_id}"
建议:改为参数化查询。

问题 2:SELECT * 可维护性差
证据:SELECT *
建议:显式列出需要字段。

问题 3:连接未关闭
证据:sqlite3.connect 后未使用上下文管理器
建议:使用 with sqlite3.connect(...) as conn。

验收标准:

失败处理:

10. 场景三:网页抓取 + 内部研究简报

10.1 目标

让模型通过 SearXNG 搜索主题,再用 Crawl4AI 抓取网页正文,生成带来源的内部简报。

10.2 输入样例

请调研最近 MCP 生态中适合企业内网使用的工具,输出 5 条以内简报,每条附来源 URL。

10.3 工具调用策略

search:
  max_results: 5
  allow_domains:
    - github.com
    - modelcontextprotocol.io
    - docs.anthropic.com
    - microsoft.github.io
crawl:
  max_pages: 5
  output_format: markdown
  timeout_seconds: 20
summary:
  require_source_url: true
  max_bullets: 5

10.4 期望输出形态

主题:MCP 企业内网工具简报

1. Playwright MCP 适合需要浏览器会话的自动化场景。
   来源:https://...
   内网适配建议:第一阶段只读账号、禁止提交表单。

2. Context7 可用于开发文档查询,但如果内网禁止外连,需要离线替代。
   来源:https://...
   内网适配建议:用内部文档索引替代外部托管服务。

验收标准:

失败处理:

11. 场景四:只读运维日报 Agent

11.1 目标

让模型读取脱敏后的日志摘要、巡检结果和变更记录,生成每日运维日报。

11.2 输入文件

data/incidents/daily_check_2026-05-25.md

# 每日巡检

- PostgreSQL 主库连接数峰值:75%
- Redis 内存使用率峰值:68%
- Kubernetes 异常重启 Pod:2 个
- 当日生产变更:1 个,已审批
- 未关闭告警:3 个

11.3 只读 Agent 脚本骨架

scripts/run_readonly_agent.py

from pathlib import Path

DATA_ROOT = Path("data/incidents").resolve()
OUTPUT_DIR = Path("outputs").resolve()
OUTPUT_DIR.mkdir(exist_ok=True)


def safe_read(relative_path: str) -> str:
    path = (DATA_ROOT / relative_path).resolve()
    if not str(path).startswith(str(DATA_ROOT)):
        raise ValueError("path outside allowed data root")
    return path.read_text(encoding="utf-8")


def write_report(name: str, content: str) -> Path:
    path = (OUTPUT_DIR / name).resolve()
    if not str(path).startswith(str(OUTPUT_DIR)):
        raise ValueError("path outside output dir")
    path.write_text(content, encoding="utf-8")
    return path


source = safe_read("daily_check_2026-05-25.md")
report = f"""# 运维日报\n\n## 原始巡检摘要\n\n{source}\n\n## 待人工确认\n\n- 异常重启 Pod 的业务影响范围\n- 未关闭告警是否需要升级\n"""
print(write_report("ops_daily_2026-05-25.md", report))

运行:

python scripts/run_readonly_agent.py

验收标准:

失败处理:

12. 记忆层设计:OpenMemory/mem0 与 Qdrant 分工

12.1 适合进入 OpenMemory/mem0 的内容

12.2 不适合进入 OpenMemory/mem0 的内容

12.3 适合进入 Qdrant 的内容

12.4 清理策略

每周:抽样检查新增记忆是否包含敏感信息。
每两周:清理重复、冲突、过期记忆。
每月:导出记忆审计报告,由系统负责人确认。

验收标准:

13. 企业安全与合规边界

13.1 数据边界

13.2 权限边界

13.3 模型边界

14. 审计日志格式

audit/tool_calls.jsonl 示例:

{"time":"2026-05-25T09:30:00+08:00","user":"alice","tool":"qdrant.search","input_hash":"sha256:...","allowed":true,"reason":"readonly retrieval"}
{"time":"2026-05-25T09:31:12+08:00","user":"alice","tool":"database.write","input_hash":"sha256:...","allowed":false,"reason":"blocked in phase 1"}

最低要求:

15. 4 周推广计划

第 1 周:单机验证

目标:跑通模型、MCP client、Qdrant、SearXNG、Crawl4AI。

交付物:

通过标准:

第 2 周:小团队试点

目标:让 3–5 名内部用户试用文档问答、代码审查、网页简报。

交付物:

通过标准:

第 3 周:策略固化

目标:把工具权限、数据目录、日志保留、审批流程固化为配置和制度。

交付物:

通过标准:

第 4 周:有限扩展

目标:扩大到 1–2 个团队,但不增加生产写权限。

交付物:

通过标准:

16. 管理层摘要

17. 最小验收清单

18. 试点完成后的决策

可以继续推进的信号

应该停止或收缩的信号

19. 附录:第一阶段推荐工具数量

原文作者的经验是:本地小模型不适合常驻过多工具,5–6 个高频工具更稳。企业内网试点可以采用以下初始组合:

必选:
1. 内部文档检索 MCP
2. Qdrant 只读检索 MCP
3. Crawl4AI 网页抓取 MCP
4. SearXNG 搜索 MCP

可选:
5. Playwright MCP,只给测试账号和只读页面
6. OpenMemory/mem0,只保存低敏偏好和环境事实

暂不建议第一阶段接入: