AI知识库怎么搭建和使用教程

文章导读
搜「AI知识库怎么搭建和使用教程」的人,多数不是从零开始,而是卡在“我已经有模型和文档,但从哪一步接上、怎么验证它真的在用自己的资料回答”这个位置。要判断这件事能不能做,先别急着选向量库:确认版本、权限、入口位置这三个前提,再用一条最短路径把“上传—切分—检索—回答”跑通一次,最后用真实文档做一次能核对答案的提问。版本、限速、额度这类会变的参数,请在模型服务商控制台的「模型列表 / API 文档
📋 目录
  1. A AI知识库之前先确认这三件事
  2. B AI知识库:最短可用路径
  3. C AI知识库:一个真实场景的完整做法
  4. D AI知识库:跑不通先查这三处
A A

搜「AI知识库怎么搭建和使用教程」的人,多数不是从零开始,而是卡在“我已经有模型和文档,但从哪一步接上、怎么验证它真的在用自己的资料回答”这个位置。要判断这件事能不能做,先别急着选向量库:确认版本、权限、入口位置这三个前提,再用一条最短路径把“上传—切分—检索—回答”跑通一次,最后用真实文档做一次能核对答案的提问。版本、限速、额度这类会变的参数,请在模型服务商控制台的「模型列表 / API 文档 / 用量与配额」页面当场查,不要照抄教程里的旧值。

搭建 AI 知识库的最小闭环是:准备可读的文档 → 切分成带元数据的片段 → 写入向量库或检索服务 → 提问时先检索再让模型按片段作答。适用场景是内部文档问答、产品手册检索这类资料可控的需求;不适合把大量非结构化数据直接丢进去指望模型自己归纳。操作时先跑通 10 份文档的小闭环,验证方式是用一个只有原文里才有的细节去提问,看回答是否命中且能给出片段出处;边界是检索命中不等于答案正确,命中率低时优先改切分和元数据,而不是先换模型。

AI知识库之前先确认这三件事

这三件事缺一件,后面都会以“看起来在跑但答非所问”的形式卡住,而且报错往往不指向真正原因。

第一,版本。包括模型服务端能调的模型名,以及本地依赖的版本。模型名在服务商控制台的「模型列表」或 API 文档的 models 字段里看;本地依赖用命令核对,避免装了个和教程不一致的大版本:

python -V
pip show openai
pip show langchain

pip show 输出的 Version 行就是实际安装版本。如果教程里的调用方式和你看到的接口字段对不上,以控制台当前文档为准,不要硬改参数去迁就旧例子。

第二,权限。要确认两件事:调用模型的 API Key 有没有读写知识库/文件上传的权限,以及你要导入的文档所在的存储你有没有读权限。API Key 的权限范围通常在控制台的「API Keys」页面按 key 查看;文件权限在 Linux 下用 ls -l 看属主和读写位,用当前运行账号实测一次能否读到:

ls -l /data/kb/docs/
head -c 200 /data/kb/docs/sample.md

head 能正常输出内容,说明运行账号可读;报 Permission denied 就是权限问题,先解决权限再谈切分。

第三,入口位置。即你的代码从哪里发起请求:是官方 SDK、兼容 OpenAI 协议的地址,还是自建服务。入口写成什么,取决于控制台「API 文档」里给出的 base_url 和鉴权方式。把入口先写进环境变量,后面所有脚本都读同一份配置,避免到处改:

export KB_BASE_URL="https://<控制台给出的地址>/v1"
export KB_API_KEY="<你的 key>"
export KB_MODEL="<模型列表里的模型名>"

入口地址、模型名、鉴权方式这三项都会变,请以控制台「API 文档」和「模型列表」页面当时显示的内容为准。

AI知识库:最短可用路径

目标不是搭完整系统,而是先让一次“基于自有文档的回答”成立。下面五步,每步一个动作,做完都有可观察的结果。

  1. 把文档放到一个固定目录。建议统一成纯文本或 Markdown 先跑通,PDF 等多格式放到第二轮。做完该看到:目录下每个文件都能被 head 正常读取。
  2. 切分并写入检索库。下面是一个可替换的骨架,用本地一个轻量向量库跑通闭环,参数按你的模型维度改:
# requirements: pip install chromadb
import os, glob, chromadb

client = chromadb.PersistentClient(path="./kb_store")
col = client.get_or_create_collection("docs")

chunk_size = 500   # 按字符切,中文场景先从小值试
overlap = 80

for path in glob.glob("/data/kb/docs/*.md"):
    text = open(path, encoding="utf-8").read()
    for i in range(0, len(text), chunk_size - overlap):
        piece = text[i:i + chunk_size]
        if not piece.strip():
            continue
        col.add(
            ids=[f"{os.path.basename(path)}-{i}"],
            documents=[piece],
            metadatas=[{"source": path, "offset": i}],
        )
print(col.count())

做完该看到:终端打印出一个大于 0 的片段数,并且 ./kb_store 目录里出现持久化文件。metadatas 里的 source 和 offset 是后面核对出处用的,不要省。

  1. 写一条检索加回答的调用。先检索再让模型只依据片段作答,这是知识库和直接聊天的分界线:
import os
from openai import OpenAI
import chromadb

client = chromadb.PersistentClient(path="./kb_store")
col = client.get_collection("docs")

question = "<换成一个只有你文档里才有的问题>"
hits = col.query(query_texts=[question], n_results=4)
context = "\n\n".join(hits["documents"][0])

llm = OpenAI(base_url=os.environ["KB_BASE_URL"], api_key=os.environ["KB_API_KEY"])
resp = llm.chat.completions.create(
    model=os.environ["KB_MODEL"],
    messages=[
        {"role": "system", "content": "只依据给定资料回答;资料里没有就回答“资料中未提及”。"},
        {"role": "user", "content": f"资料:\n{context}\n\n问题:{question}"},
    ],
)
print(resp.choices[0].message.content)

做完该看到:回答里出现你文档中的具体说法。如果模型说“资料中未提及”,先打印 hits["documents"][0] 看检索是不是就没召回,而不是怀疑模型。

AI知识库怎么搭建和使用教程
  1. 回到出处核对。用 hits["metadatas"][0] 里的 source 和 offset 打开原文件对应位置,确认这段话确实存在。做完该看到:回答与原文一致,或明确发现是切分把上下文切断了。
  2. 再加第二个问题。换一个和上一个问题不同的知识点重复第 3、4 步。两个问题都能命中,才算最短闭环跑通。

AI知识库:一个真实场景的完整做法

场景设定:一个内部产品团队有约 60 份 Markdown 格式的接口说明和操作手册,单个文件多在 5KB 到 40KB 之间,需要让同事提问“某个字段的含义”和“某个操作的前置条件”。数据量不大,用本地向量库足够,不必上集群。

配置取值和位置如下:

  • 文档目录:/data/kb/docs/,在服务器上创建,权限用 chmod 让运行账号可读;
  • 切分参数:chunk_size=500、overlap=80,写在上面脚本的常量区。手册类文档按段落切通常比拼字符更稳,若原文有小标题,可以先按“## ”切一次再按长度截断;
  • 检索条数:n_results=4,写在 col.query 调用处。文档少时先给 3 到 5 条,太多会把无关片段带进上下文;
  • 模型名与地址:来自控制台「模型列表」和「API 文档」,写进 KB_MODEL、KB_BASE_URL 环境变量,脚本不写死;
  • 提示词约束:写在第 3 步 messages 的 system 里,明确“只依据资料回答”和“无依据就说未提及”。

实际跑的顺序是:先只导入 10 份接口说明形成第一版 kb_store,用“某个字段是否必填”这类问题验证;命中后再把剩下的手册全量导入。全量导入后要重跑同样的两个问题,确认旧问题没有被新片段挤掉。这个顺序的价值在于:出问题时你知道是切分变了还是数据变了。

这套做法不适用的地方也要说清楚:如果文档里有大量表格或扫描件,纯文本切分会丢结构,需要先做结构化提取;如果问题需要跨多份文档做汇总统计,单轮检索加回答容易漏,得改成多轮检索或先用脚本统计再交给模型表述。

AI知识库:跑不通先查这三处

按出现频率从高到低排,每处都给判断方法。

第一处:检索没召回,模型答“资料中未提及”

页面或终端提示通常是模型返回了“资料中未提及”这类句子,而不是报错。判断方法:在检索调用后立刻打印命中的片段和距离值,

print(hits["documents"][0][:300])
print(hits["distances"][0])

如果片段和问题明显无关,检查切分是否把一句话切断、文档是否真的写进了 kb_store(用 col.count() 对比文件数估算片段量)。这一步的修改优先顺序是:调切分方式 → 补元数据 → 换 embedding 模型,先不要换对话模型。

第二处:鉴权或地址错误

常见报错形如 401 Unauthorized、403 Forbidden,或连接超时、域名解析失败。判断方法:确认 KB_BASE_URL 是否带了正确的路径前缀(很多兼容接口要求以 /v1 结尾),确认 KB_API_KEY 没有多余空格,并查看控制台「API Keys」页面确认该 key 是否被禁用或权限不足。如果本机 curl 能通而脚本不通,问题通常在环境变量没有传进运行进程,用 env | grep KB_ 检查。

第三处:模型名或参数不被接受

常见报错形如 model not found、invalid request 或提示上下文长度超限。判断方法:到控制台「模型列表」核对模型名逐字符一致(大小写和连字符都算),并检查送进去的片段是否过多导致超长。降低 n_results 或 chunk_size 是最直接的收敛方式;不要靠删掉 system 里的约束去绕过长度限制,那会让回答失去依据。

这三处的共同点是:报错信息往往只说明“调用失败”,不说明“知识库有问题”。养成每次改动只动一个变量的习惯,并用同一个只有原文才有的细节问题做回归,判断成本会低很多。