从模型 API 到企业知识库与智能助手

📅 2026/7/30 8:40:09 👁️ 阅读次数 📝 编程学习
从模型 API 到企业知识库与智能助手

从模型 API 到企业知识库与智能助手

本文默认已经完成本地大模型部署,并且可以通过 vLLM、Ollama 或其他 OpenAI 兼容服务正常调用模型。本文重点讨论模型“能运行”之后,如何逐步建设企业知识库、业务工具、质量评估、权限控制和可观测能力。

前言

很多人在完成本地大模型部署后,会立即遇到一个问题:

模型已经能正常回答问题了,下一步应该做什么?

此时往往会出现几种常见误区:

  • 立刻开始微调模型;
  • 把公司全部文件一次性导入知识库;
  • 直接让模型连接数据库;
  • 一开始就建设“什么都能做”的企业智能助手;
  • 只关注模型回答效果,不记录知识来源和执行过程。

实际上,本地模型能够返回一段文字,只说明最底层的推理服务已经启动成功,并不代表它已经成为一个可用于企业生产环境的系统。

一个真正可用的企业 AI 应用,至少还需要解决以下问题:

  1. 模型服务是否稳定;
  2. 如何让模型使用企业资料;
  3. 如何保证回答有真实依据;
  4. 如何控制不同用户可访问的知识范围;
  5. 如何调用企业内部接口;
  6. 如何判断答案是否正确;
  7. 如何定位错误、循环和性能问题;
  8. 如何持续更新知识,而不是频繁重新训练模型。

本文将搭建一个最小但完整的企业知识助手,实现:

本地大模型 + 企业文档解析 + BGE-M3 向量模型 + Qdrant 向量数据库 + FastAPI 问答接口 + 文档来源引用 + 部门权限过滤 + 后续工具调用与评估扩展

一、本地模型部署成功,不等于企业 AI 已经建设完成

本地大模型系统可以分成五层:

第五层:业务应用 智能问答、运维助手、客服助手、研发助手 第四层:Agent 与工具 查询数据库、调用接口、执行工作流、提交审批 第三层:知识与检索 文档解析、切分、Embedding、检索、重排、引用 第二层:模型服务 vLLM、Ollama、推理 API、并发、显存、上下文 第一层:基础设施 GPU、驱动、CUDA、Linux、Docker、存储、网络

完成本地模型部署,只代表第二层基本可用。

接下来最重要的工作,不是继续寻找更大的模型,而是把上层能力逐步补齐。


二、先判断问题应该用哪种技术解决

企业在使用大模型时,经常把所有问题都归结为“需要训练模型”。

实际上,不同问题应该使用不同方案。

需求更适合的方案
回答公司制度、产品文档和项目资料RAG 企业知识库
查询订单、库存、设备和服务状态工具调用或内部 API
固定回答格式和输出结构Prompt 或结构化输出
统一语言风格和表达方式Prompt,必要时再微调
学习稳定的专业任务模式SFT 或 LoRA 微调
获取经常变化的数据RAG 或实时工具,不应写进模型参数
限制用户访问范围身份认证、权限过滤和数据隔离
判断回答质量测试集、自动评估和人工反馈

一个比较合理的建设顺序是:

模型 API ↓ Prompt 约束 ↓ 企业知识库 RAG ↓ 工具调用 ↓ 质量评估 ↓ 可观测与审计 ↓ 确定仍有必要后再微调

2.1 为什么不建议第一步就微调

微调更适合改变模型的行为方式,例如:

  • 固定分类规则;
  • 固定业务流程;
  • 固定输出格式;
  • 学习某类专业任务的示例;
  • 统一术语和语言风格。

但公司制度、产品参数、项目进度、客户资料和接口数据经常变化。

如果把这些动态知识全部通过微调写进模型,会产生几个问题:

  • 资料更新后需要重新制作训练数据;
  • 很难删除已经写入参数的旧知识;
  • 很难证明答案来自哪份资料;
  • 不同部门权限难以隔离;
  • 模型仍然可能把旧知识和新知识混在一起。

因此,企业建设的第一阶段通常应该优先使用 RAG,而不是微调。


三、先给模型服务做一次验收

在接入知识库之前,先确认模型 API 本身稳定。

假设 vLLM 地址为:

http://127.0.0.1:8000/v1

3.1 检查模型列表

curlhttp://127.0.0.1:8000/v1/models

3.2 检查普通问答

curlhttp://127.0.0.1:8000/v1/chat/completions\-H"Content-Type: application/json"\-d'{ "model": "qwen-local", "messages": [ { "role": "user", "content": "只回答OK" } ], "temperature": 0.1, "max_tokens": 16, "stream": false }'

预期结果中应包含:

{"choices":[{"message":{"content":"OK"},"finish_reason":"stop"}]}

3.3 建立基础验收指标

至少记录:

模型名称 启动参数 最大上下文 首 Token 延迟 总响应耗时 输入 Token 输出 Token 并发请求数 请求成功率 GPU 显存使用量 异常退出次数

不要只测试一次curl成功,就认为服务已经可以交付。

正式接入业务前,至少准备 20~50 个固定问题作为模型基线测试集。每次修改模型、Prompt、量化方式或推理参数后,都重新执行这些问题。


四、选择第一个业务场景

企业 AI 的第一版不应该从“全能助手”开始。

建议选择同时满足以下条件的场景:

  • 用户问题比较集中;
  • 公司已经有可用资料;
  • 答案能够被人工验证;
  • 即使回答失败,也不会直接造成严重业务后果;
  • 使用频率足够高;
  • 能够明确统计节省的时间。

适合作为第一阶段的场景包括:

公司制度问答 产品资料问答 项目实施手册问答 开发规范助手 运维手册助手 售后知识助手 标准方案生成助手

不建议第一阶段直接开放:

自动修改生产数据库 自动执行服务器命令 自动审批付款 自动删除文件 不经确认调用高风险接口

第一阶段的目标应该是:

让模型基于指定资料,稳定回答一个边界清晰的问题,并且能够显示引用来源。


五、企业知识库最重要的不是模型,而是资料治理

知识库效果不好,很多时候不是模型能力不足,而是资料本身存在问题。

常见情况包括:

  • 同一个制度存在多个版本;
  • 文件名无法说明内容;
  • 扫描 PDF 无法提取文本;
  • 表格没有标题和字段说明;
  • 重要结论隐藏在聊天记录中;
  • 文档没有部门和权限标识;
  • 已废止的制度仍然被检索到;
  • 产品名称和内部简称不统一;
  • 一份文件同时包含多个完全不同的主题。

5.1 推荐的资料目录

knowledge/ ├── raw/ # 原始资料 │ ├── hr/ │ ├── product/ │ ├── project/ │ ├── development/ │ └── operations/ ├── normalized/ # 清洗后的标准文本 ├── metadata.json # 文档元数据 ├── rejected/ # 暂不入库的文件 └── evaluation/ # 测试问题和标准答案

5.2 每份资料至少需要这些元数据

{"doc_id":"HR-EMPLOYEE-HANDBOOK","title":"员工手册","department":"hr","version":"2026.07","status":"active","permission":"internal","owner":"人力资源部","updated_at":"2026-07-20","source":"员工手册V3.docx"}

最关键的字段是:

唯一文档编号 标题 版本 状态 所属部门 权限范围 更新时间 原始来源

5.3 资料进入知识库前的检查清单

[ ] 是否为当前有效版本 [ ] 是否存在重复文件 [ ] 是否包含敏感信息 [ ] 是否明确所属部门 [ ] 是否明确可访问范围 [ ] 是否能够提取正文 [ ] 标题是否能表达文档内容 [ ] 表格是否有字段名称 [ ] 图片中的重要文字是否已经转成文本 [ ] 是否指定资料维护负责人

六、本文使用的最小 RAG 架构

本文实现以下链路:

┌─────────────────┐ │ 本地 Qwen/vLLM │ │ OpenAI 兼容接口 │ └────────▲────────┘ │ │ 组合 Prompt │ ┌────────┐ HTTP ┌───────┴────────┐ │ 用户端 │ ─────────────→ │ FastAPI RAG API │ └────────┘ └───────┬────────┘ │ 问题向量化与权限过滤 │ ┌────────▼────────┐ │ Qdrant │ │ 向量 + 文本元数据 │ └────────▲────────┘ │ ┌────────┴────────┐ │ BGE-M3 │ │ Embedding 模型 │ └─────────────────┘

vLLM 可以提供 OpenAI 兼容的 Chat Completions 等接口,因此上层应用可以使用 OpenAI Python SDK,并将base_url指向本地服务。

BGE-M3 输出 1024 维向量,支持多语言,并能够用于密集、稀疏和多向量检索。本文为了降低第一版复杂度,先使用密集向量检索,后续再增加混合检索和重排。

Qdrant 中每个知识片段保存为一个 Point:

Point ├── id ├── vector └── payload ├── text ├── title ├── source ├── department ├── version └── chunk_index

Payload 不只是展示来源,还可以用于部门、状态、版本和权限过滤。


七、创建项目目录

mkdir-pcompany-rag/appmkdir-pcompany-rag/scriptsmkdir-pcompany-rag/knowledge/rawcdcompany-rag

目录结构:

company-rag/ ├── docker-compose.yml ├── requirements.txt ├── .env ├── metadata.json ├── knowledge/ │ └── raw/ ├── scripts/ │ └── ingest.py └── app/ ├── __init__.py └── main.py

八、使用 Docker 启动 Qdrant

创建docker-compose.yml

services:qdrant:image:qdrant/qdrant:latestcontainer_name:company-rag-qdrantrestart:unless-stoppedports:-"6333:6333"-"6334:6334"volumes:-qdrant-data:/qdrant/storagevolumes:qdrant-data:

启动:

dockercompose up-d

查看状态:

dockercomposeps

访问管理界面:

http://127.0.0.1:6333/dashboard

正式环境建议:

  • 固定经过验证的 Qdrant 镜像版本;
  • 不直接把管理端口暴露到公网;
  • 配置备份;
  • 为需要过滤的 Payload 字段建立索引;
  • 对不同环境使用独立 Collection。

九、准备 Python 环境

创建虚拟环境:

python3.11-mvenv .venvsource.venv/bin/activate

创建requirements.txt

fastapi uvicorn[standard] openai>=1.26 qdrant-client sentence-transformers python-dotenv pydantic pypdf python-docx

安装:

pipinstall-rrequirements.txt

9.1 双 3090 环境中的资源安排

如果本地大模型已经通过 Tensor Parallel 占用了两张 RTX 3090,不要默认再把 Embedding 模型放到 GPU。

第一版可以这样安排:

GPU 0 + GPU 1:Qwen/vLLM CPU + 内存:BGE-M3 Embedding

你的机器如果有较强 CPU 和较大内存,这种方案可以先运行起来,只是批量导入资料时速度会慢一些。

后续可以选择:

  • 为 Embedding 单独预留一张 GPU;
  • 在模型低峰期离线生成文档向量;
  • 将 Embedding 独立部署成服务;
  • 使用更轻量的中文或多语言 Embedding 模型;
  • 对查询向量增加缓存。

十、配置环境变量

创建.env

LLM_BASE_URL=http://127.0.0.1:8000/v1LLM_API_KEY=EMPTYLLM_MODEL=qwen-localQDRANT_URL=http://127.0.0.1:6333QDRANT_COLLECTION=company_knowledgeEMBEDDING_MODEL=BAAI/bge-m3EMBEDDING_DEVICE=cpuRETRIEVAL_TOP_K=8CONTEXT_TOP_K=4

如果模型服务在宿主机,而 RAG 应用运行在 Docker 中,不能继续使用容器自身的127.0.0.1,应根据部署环境改成宿主机地址或同一 Docker 网络中的服务名。


十一、准备示例资料和元数据

创建:

knowledge/raw/hr/employee_handbook.md

内容示例:

# 员工请假制度 员工申请年假,应至少提前一个工作日提交申请。 连续请假三天及以上,需要由部门负责人审批。 紧急情况下可以先通过电话或即时通信工具告知直属负责人,并在返岗后补交申请。

创建metadata.json

{"hr/employee_handbook.md":{"doc_id":"HR-EMPLOYEE-HANDBOOK","title":"员工手册","department":"hr","version":"2026.07","status":"active","permission":"internal","owner":"人力资源部"}}

十二、实现文档导入程序

创建scripts/ingest.py

importhashlibimportjsonimportosimportsysimportuuidfrompathlibimportPathfromtypingimportAnyfromdocximportDocumentfromdotenvimportload_dotenvfrompypdfimportPdfReaderfromqdrant_clientimportQdrantClient,modelsfromsentence_transformersimportSentenceTransformer load_dotenv()BASE_DIR=Path(__file__).resolve().parent.parent KNOWLEDGE_DIR=BASE_DIR/"knowledge"/"raw"METADATA_FILE=BASE_DIR/"metadata.json"QDRANT_URL=os.getenv("QDRANT_URL","http://127.0.0.1:6333",)QDRANT_COLLECTION=os.getenv("QDRANT_COLLECTION","company_knowledge",)EMBEDDING_MODEL=os.getenv("EMBEDDING_MODEL","BAAI/bge-m3",)EMBEDDING_DEVICE=os.getenv("EMBEDDING_DEVICE","cpu",)VECTOR_SIZE=1024CHUNK_SIZE=800CHUNK_OVERLAP=120defread_file(path:Path)->