普通开发者如何搭一套个人知识库Agent:从RAG到记忆机制

技术开发RAGAgent知识库向量数据库LangChainLlamaIndex私有化2026-09-06
封面图由AI生成,仅用于示意。本文为原创实战教程,文中出现的产品/框架商标归各自所有者所有,不构成商业推荐。
先问你一个问题:如果个人知识库里只有几十篇文档,为什么还需要一套“Agent”?因为你要的不是搜索引擎,而是能“读懂”你文档的助手。这个助手最少包含:加载与解析、向量检索、生成、短期会话记忆、长期用户画像。

1. 选型对照:LangChain vs LlamaIndex vs 自研

对比项LangChainLlamaIndex自研
定位快速编排 Agent/多工具专注知识库检索管线结构最简单、可控性最强
上手速度中高低
链路复杂度高中低
适合场景需要接外部工具文档问答、知识Agent研究学习或轻量固定场景
我的建议是:如果你的核心场景只是“私有文档问答”,先用 LlamaIndex 把原型跑通,再逐步把高频模块改成自研。LangChain 适合需要接多个外部工具或复杂 Agent 循环时再引入。不要为了用框架而用框架;你的第一个知识库也许不需要一条 2000 行的 Chain。

2. 嵌入模型与向量数据库的取舍

嵌入模型维度本地推理中文表现适合情况
bge-m31024可用强不追求小体积
bge-small-zh-v1.5512省内存较好CPU/小内存原型
text-embedding-3-small1536API好可接受外发文本
向量库方面,个人知识库没必要一上来就部署 Milvus。我这里给出一条务实路径:
向量库资源占用适合规模一句话
Chroma低100 万级嵌入式,快速起步
LanceDB低千万级文件型列式存储
Milvus高十亿级更适合团队/企业
个人项目建议试 Chroma 或 LanceDB。选择时看两件事:是否支持 metadata filter(比如按日期、目录过滤),以及增量写入是否稳定。

3. 解决“召回正确但答案错误”的分块与重排技巧

“向量检索到了正确文档,但答案仍然错”通常不是 embedding 的问题,而是上下文结构错乱。常见原因:
  • 按固定 512 token 硬切,把一段完整业务逻辑切到两个块里。
  • 没有保留标题与段落层级,LLM 不知道这段文字来自“2026年报”还是“Q1管理层问答”。
  • Top-K 取太大,次要文本淹没了关键文本。
我建议使用“父子块 + 重排”的组合方案:
  • 小块负责匹配,如 200~250 token;
  • 父块负责交给模型生成,如 600~1200 token;
  • 先向量召回 Top50,再用 rerank 模型压缩到 Top3~5。
flowchart LR A[原始文档] --> B[解析标题与段落] B --> C[父子块索引] Q[查询] --> D[向量召回 Top50] C --> D D --> E[Rerank Top5] E --> F[重排后的父块] F --> G[LLM 生成]
分块小技巧:Markdown 文件先按 `##` 分节,再对一节中长度过大的段落继续切;如果一段是表格,不要切成两半。Rerank 使用本地 `bge-reranker-v2-m3` 即可,个人场景性价比很高。

4. 加入会话记忆与长期用户画像的简单实现

一个没有记忆的知识库是“一次性百宝箱”。我建议记忆分为两层: 短期层:保存最近 10~20 轮对话,用于多轮澄清和追问。 长期层:定期抽取用户画像,比如关注领域、术语习惯、历史结论。使用 SQLite 保存,避免引入强依赖。 表结构可以这样设计:
CREATE TABLE chat_history (
 session_id TEXT,
 role TEXT,
 content TEXT,
 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE user_profile (
 user_id TEXT PRIMARY KEY,
 profile_json TEXT,
 updated_at TIMESTAMP
);
Python 示例:
# memory.py 示例:SQLite 版短期记忆
import sqlite3
DB_PATH = './agent_memory.db'
def init_db():
 conn = sqlite3.connect(DB_PATH)
 conn.execute('''
 CREATE TABLE IF NOT EXISTS chat_history (
 session_id TEXT,
 role TEXT,
 content TEXT,
 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
 )
 ''')
 conn.commit()
 conn.close()
def save_message(session_id, role, content):
 conn = sqlite3.connect(DB_PATH)
 conn.execute(
 'INSERT INTO chat_history(session_id, role, content) VALUES(?, ?, ?)',
 (session_id, role, content)
 )
 conn.commit()
 conn.close()
当 token 预算不够时,加载最近消息后做一轮“摘要改写”:把超过 10 轮的历史压缩成 3 条 summary,再放进 system prompt。用户画像的更新不需要频繁,可以在每次会话结束后异步触发一次。

5. 私有化部署成本估算与性能瓶颈

先给一个“本地个人版”的成本量级。假设你手上有一台 16GB 内存的 PC 或 Mini 主机,只服务自己一个人:
模块选用额外硬件成本说明
向量库Chroma0 元写入本地磁盘
Embeddingbge-small-zh-v1.50 元CPU 即可
生成模型Ollama + qwen2.5:7b-instruct-q40 元需要约 6~8GB 内存
Rerankbge-reranker-v2-m30 元必要时只处理 Top20
通常瓶颈不在“容量”,而在这 4 处:
  • PDF 解析慢,尤其扫描版需要 OCR;
  • Embedding 首次建索引慢,但后续增量可以接受;
  • Rerank 和 LLM 在本地抢内存,容易 OOM;
  • Prompt 过大导致首 token 延迟升高。
如果你是租云服务器,建议先跑 API 验证,再购买 GPU 实例。具体价格随地域与活动变化,这里不做报价;只是提醒:个人知识库的主要费用往往是“调试时间”,不是硬件费。

6. 示例代码与常见坑

下面是一个能直接改造成后台任务的最小骨架:
# mini_agent.py
import sqlite3
DB_PATH = './agent_memory.db'
def init_db():
 conn = sqlite3.connect(DB_PATH)
 conn.execute('''
 CREATE TABLE IF NOT EXISTS chat_history (
 session_id TEXT,
 role TEXT,
 content TEXT
 )
 ''')
 conn.commit()
 conn.close()

先用一段普通文本代替真实向量检索

def fake_retrieve(query): return ['片段一:项目背景', '片段二:技术方案'] def build_context(retrieved, query): parts = [] parts.append('Knowledge base:') parts.extend(['- ' + p for p in retrieved]) parts.append('Question: ' + query) return '\n'.join(parts) if __name__ == '__main__': init_db() q = '2026年总结论是什么?' docs = fake_retrieve(q) ctx = build_context(docs, q) print(ctx)
这份代码的要点是:先有一个可跑的 shell,再把 `fake_retrieve` 替换成 Chroma + bge,最后接 Ollama。 常见坑:
  • 把标题、来源、时间写入 chunk 的 metadata,而不是只存文本。
  • 不要选太复杂的向量库,除非确有必要。
  • 中文文本请使用带中文分词的加载器,否则会把一句话从中间切开。
  • 不要把“用户提问”和“历史对话”拼成同一个字符串,建议保留 role 字段。
  • 本地并发访问 SQLite 记得开启 WAL 模式,避免锁库。

推荐视频(出处标注)

平台搜索关键词出处摘要
B站RAG 实战B站搜索页
腾讯视频知识库 Agent腾讯视频搜索页
优酷大模型检索增强优酷搜索页
抖音RAG 记忆机制抖音搜索页
注:视频出处以各平台播放页实际作者为准;本文只提供检索入口。

操作清单

  • 准备 10~20 个代表性文档,先转成 Markdown/TXT。
  • 选一个轻量嵌入模型,在本地跑通 embedding 调用。
  • 实现按标题分块,记录 source 和 page 元数据。
  • 用 Chroma 建立父子块索引。
  • 加入 rerank,用 5 个棘手问题做回归测试。
  • 接入 sqlite 记忆表,验证多轮连续问答。
  • 用 Ollama 加载量化模型,调好 Prompt 模板。
  • 定期备份向量目录与 agent_memory.db。

避坑指南

  • 别相信默认分块器;先用 3 个文件人工验证召回片段。
  • 别把 metadata 放在 prompt 最后,LLM 会忽略它;建议放在 system 开头或紧跟用户问题。
  • 别盲目调 Top-K;K 越大,模型越容易被噪声带走。
  • 别在没做 rerank 前就换更大的基础模型,多加优化可能更有效。
  • 别把用户画像写成百科全书,每次只更新变化字段,避免 profile 越来越长。

免责声明

本文仅代表个人开发经验总结,不构成任何购买或商用建议。文中涉及的代码仅供学习参考,使用前请根据自身数据和模型许可证进行合规审查。如你在真实项目中复用,请自行承担部署安全与数据隐私责任。
PREMIUM

需要完整版教程?

包含详细步骤、视频演示、提示词模板和可下载资料包。微信支付即时获取。

购买完整版 ¥29.90