【踩坑复盘】我在本地跑 RAG 知识库时踩了 5 个大坑,吐血整理避坑指南

前言

大家好,我是去年开始研究 RAG 的后端开发。

本地跑通一个 RAG 知识库听着简单------不就是"文档切分 → 向量化 → 检索 → LLM 生成"吗?但真正动手时,各种奇奇怪怪的坑一个接一个。

花了 2 周踩坑,终于把系统跑通了。 这篇文章把我踩过的 5 个大坑整理出来,避免大家再走弯路。


坑 1:LM Studio API Token 被坑了一整天 🔥

调用 http://localhost:1234/api/v1/chat 时,开始完全不报错------能正常返回。后来突然开始报:

css 复制代码
An LM Studio API token is required to make requests to this server,
but none was provided using the Authorization header

我以为 Token 过期了,重启 LM Studio、重新生成 Token,还是一样。

最后发现:LM Studio 有两套 API!

API 类型 端点 Token
Local Server API /v1/chat/completions ✅ 需要 Bearer Token
Developer API /api/v1/chat 部分版本免 Token
java 复制代码
// ✅ 正确:Local Server API + Bearer Token
String url = lmstudioUrl + "/v1/chat/completions";

Request request = new Request.Builder()
    .url(url)
    .addHeader("Authorization", "Bearer " + apiKey)  // 关键!
    .addHeader("Content-Type", "application/json")
    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
    .build();

// ❌ 错误:Developer API 免 Token 的写法,不通用
String url = lmstudioUrl + "/api/v1/chat";

关键点:看清楚你调的是哪套 API,Token 策略完全不同!


坑 2:Embedding 向量维度不匹配,Qdrant 存储报错 🔥

向量化存储时报错:

vbnet 复制代码
Response: BadRequest:{"status":{"error":"Wrong vector dimension...

我的 Embedding 模型是 text-embedding-bge-base-zh-v1.5,理论上输出 768 维向量。但 Qdrant 创建 Collection 时,我用了默认维度 1024。

先测一次向量维度:

json 复制代码
curl http://localhost:1234/v1/embeddings \
  -H "Authorization: Bearer $LM_API_TOKEN" \
  -d '{"model":"text-embedding-bge-base-zh-v1.5","input":["测试文本"]}'

返回结果里数组长度就是真实维度。

创建 Qdrant Collection 时指定正确维度:

scss 复制代码
// ✅ 正确
qdrantClient.createCollection(
    CollectionName,
    VectorParams.builder()
        .size(768)  // 和 Embedding 模型输出维度一致!
        .distance(Distance.Cosine)
        .build()
);

// ❌ 错误:用错了维度
.size(1024)  // 导致存储失败

避坑建议: 把向量维度写成配置项:

yaml 复制代码
# application.yml
qdrant:
  vector-dimension: 768

坑 3:文本切分把句子拦腰截断,回答质量断崖式下降 🔥

早期用的是纯长度切分:

arduino 复制代码
// ❌ 简单粗暴的切分------把句子拦腰截断
String chunk = text.substring(i, i + 1000);

结果:检索出来的片段经常是半截句子,LLM 完全无法理解。

比如切到"公司成立于 201"------LLM 根本不知道后面是什么。

scss 复制代码
public List<String> chunkText(String text) {
    List<String> chunks = new ArrayList<>();
    StringBuilder current = new StringBuilder();

    // ✅ 按句子边界分割(中文:。!?;\n)
    String[] sentences = text.split("(?<=[。!?.!?;;\n])");

    for (String sentence : sentences) {
        // 当前块加上这句超过阈值
        if (current.length() + sentence.length() > chunkSize) {
            // 保存当前块
            if (current.length() > 0) {
                chunks.add(current.toString().trim());
            }

            // 保留重叠部分(避免丢失上下文)
            int overlapLen = Math.min(chunkOverlap, current.length());
            current = new StringBuilder(
                    current.toString().substring(current.length() - overlapLen)
            );
        }
        current.append(sentence);
    }

    if (current.length() > 0) {
        chunks.add(current.toString().trim());
    }
    return chunks;
}

加上重叠(Overlap)效果更好:

ini 复制代码
Chunk1: [句子1][句子2][句子3]...
Chunk2: [...句子3][句子4][句子5]...  ← 重叠部分保证上下文连续

坑 4:LM Studio Embedding 接口不稳定(/v1/embeddings) 🔥

部分版本的 LM Studio,/v1/embeddings 接口返回错误:

json 复制代码
{"error": "model not found"}

但明明 v1/models 里能看到这个模型。

原因

LM Studio 对 Embedding 模型的支持比较微妙,有些 GGUF 格式的 Embedding 模型在部分版本中不稳定。

解决方案

换成 Ollama 运行 Embedding

bash 复制代码
# 安装 Ollama
winget install Ollama.Ollama

# 下载 Embedding 模型(nomic-embed-text,约 274MB)
ollama pull nomic-embed-text

# 启动
ollama serve

修改配置:

yaml 复制代码
# application.yml
ollama:
  base-url: http://localhost:1234  # 如果 LM Studio 在这里
  embeddings-model: nomic-embed-text

# 改成 Ollama:
ollama:
  base-url: http://localhost:11434
  embeddings-model: nomic-embed-text

坑 5:向量检索相似度阈值设错,噪声答案满天飞 🔥

系统上线后,经常出现"答非所问"的情况------检索出来的片段和用户问题根本不相关,但 LLM 硬是"强行回答"了。

看了日志,发现检索出来的片段相似度只有 0.1~0.2(理论上 0.5+ 才算相关),但都被塞进 Prompt 里了。

scss 复制代码
public List<SearchResult> search(String query, int topK) {
    List<SearchResult> allResults = qdrantClient.search(...);

    // ✅ 加阈值过滤:只返回相似度 >= 0.3 的结果
    return allResults.stream()
            .filter(r -> r.getScore() >= 0.3)
            .limit(topK)
            .collect(Collectors.toList());
}

不同 Embedding 模型相似度分布不同,建议先跑几个测试:

Embedding 模型 优质答案阈值
bge-base-zh-v1.5 ≥ 0.5
nomic-embed-text ≥ 0.6
text-embedding-v2 ≥ 0.55

总结一下: 5 个坑一次排雷

原因 解决
LM Studio Token 不一致 两套 API 混用 统一用 Local Server API + Bearer Token
向量维度不匹配 Qdrant 维度写错 先测试实际维度再创建 Collection
文本切分截断句子 纯长度切分 按句子边界切分 + 重叠
Embedding 接口不稳定 LM Studio 版本问题 换成 Ollama 或在线 API
噪声答案满天飞 无阈值过滤 score >= threshold 过滤

相关推荐
格林威几秒前
C#高位深相机图像保存:12位16位图像保存方案,OpenCvSharp和Halcon实现
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
zx_741484811 分钟前
【计算机视觉入门】两大 OpenCV 案例:答题卡判分与图像全景拼接
人工智能·opencv·计算机视觉
樊小肆2 分钟前
DeepSeeker-Code源码导读10-代码智能tsHost
人工智能·agent
武子康4 分钟前
262K 跑过,128K 却被脚本拦下:A6000 跑分里的三种“失败”不能混为一谈
人工智能·llm·agent
互联网志4 分钟前
机器人物理AI操作系统问世 多形态设备协同训练重构智能作业模式
人工智能·重构·机器人
Zguigo5 分钟前
【DL】神经网络学习目标|prediction|Loss|Gradient
人工智能·神经网络·学习
长江后浪博客9 分钟前
RIP 颜色计算原理:RGB→CMYK 转换与陶瓷喷墨色彩管理
人工智能·rip·颜色管理·陶瓷喷墨
2601_9669496514 分钟前
Python 量化数据质量校验:如何确保股票历史日线数据不存在缺失交易日?
开发语言·人工智能·爬虫·python·量化策略·量化·quantdash
阳火锅20 分钟前
领导夸我日报越写越详细了,其实我只敲了 npm run commit
前端·javascript·人工智能
Aloudata21 分钟前
企业级 AI 问数安全指南:如何兼顾可用性、权限与审计?
大数据·人工智能·数据分析·agent·语义编织