1314 字
7 分钟
手把手教你搭一个个人AI知识库:从零到可用的完整流程
手把手教你搭一个个人AI知识库:从零到可用的完整流程
我有一个习惯:看到好的技术文章、文档片段、代码方案都会存下来。存了一年之后,我的笔记文件夹里有大概800个文件。
问题是:存了等于没存。因为真遇到一个问题的时候,我不会去翻那800个文件。
于是我决定做一个能”对话”的知识库——把笔记丢进去,然后用自然语言提问。
方案选择
我先列了几个要求:
- 本地运行——笔记里有公司的内容,不方便传到云端
- 低成本——个人项目,不想花钱
- 能跑就行——不追求生产级,先能用起来
最后选的组合:
- Ollama——跑本地模型
- Chroma——向量存储(本地,零配置)
- Python——胶水语言
- Qwen2.5-7B量化版——中文能力好的小模型
这个组合的优点是:全部免费、全部本地、全部能在自己的机器上搞定。
第一步:准备环境
# 安装Ollama(Mac/Linux)curl -fsSL https://ollama.com/install.sh | sh
# Windows去官网下载
# 下载模型ollama pull qwen2.5:7b
# 安装Python依赖pip install chromadb sentence-transformers langchain如果你用的是Windows,Python依赖最好用虚拟环境装,避免跟系统Python冲突。
第二步:处理你的文档
知识库的第一步是把你的文件变成向量。
我笔记的格式比较乱——有Markdown、有TXT、甚至有几个Word文档。所以我先做了统一转换:全部转成纯文本。
import osfrom pathlib import Path
def read_all_docs(directory: str) -> list[dict]: """读取目录下所有文档""" docs = [] for filepath in Path(directory).rglob('*'): if filepath.suffix in ['.md', '.txt', '.py', '.js']: content = filepath.read_text(encoding='utf-8') docs.append({ "content": content, "source": str(filepath), "title": filepath.stem }) return docs
documents = read_all_docs("./my-notes")print(f"共读取 {len(documents)} 个文档")然后切分。这里我用了一个简单的策略:按段落切分,每段不超过500个字符。
def split_into_chunks(docs: list[dict], chunk_size: int = 500) -> list[dict]: """按段落切分文档""" chunks = [] for doc in docs: paragraphs = doc["content"].split("\n\n") current_chunk = "" for para in paragraphs: if len(current_chunk) + len(para) > chunk_size: if current_chunk: chunks.append({ "content": current_chunk.strip(), "source": doc["source"], "title": doc["title"] }) current_chunk = para else: current_chunk += "\n\n" + para if current_chunk else para
if current_chunk.strip(): chunks.append({ "content": current_chunk.strip(), "source": doc["source"], "title": doc["title"] }) return chunks
chunks = split_into_chunks(documents)print(f"切分为 {len(chunks)} 个片段")我的800个文档切完之后变成了大约3500个片段。
第三步:向量化并存储
import chromadbfrom sentence_transformers import SentenceTransformer
# 加载Embedding模型embedder = SentenceTransformer("shibing624/text2vec-base-chinese")
# 连接Chromaclient = chromadb.PersistentClient(path="./knowledge-db")collection = client.get_or_create_collection("my-knowledge")
# 批量处理(避免一次全部塞进去内存爆炸)batch_size = 100for i in range(0, len(chunks), batch_size): batch = chunks[i:i+batch_size] texts = [c["content"] for c in batch]
# 生成向量 embeddings = embedder.encode(texts).tolist()
# 存储 collection.add( documents=texts, embeddings=embeddings, metadatas=[{"source": c["source"], "title": c["title"]} for c in batch], ids=[f"chunk_{i+j}" for j in range(len(batch))] )
print(f"已处理 {i+len(batch)}/{len(chunks)} 个片段")这个过程在我的机器上跑了大约10分钟。800个文档不算多,如果你有上万个文件,建议分批跑。
第四步:查询
def query_knowledge(question: str, top_k: int = 3) -> list[dict]: """查询知识库""" # 生成查询向量 query_vector = embedder.encode([question]).tolist()
# 检索 results = collection.query( query_embeddings=query_vector, n_results=top_k )
return [ { "content": doc, "source": meta["source"], "title": meta["title"] } for doc, meta in zip(results["documents"][0], results["metadatas"][0]) ]
# 试试results = query_knowledge("如何在Python中处理JSON?")for r in results: print(f"来源: {r['title']} ({r['source']})") print(f"内容: {r['content'][:100]}...") print()到这里,纯检索部分就完成了。你能通过自然语言问题找到最相关的笔记片段。
第五步:加一个LLM让它能对话
光检索还不够——你拿到的是几个文本片段,需要自己读。加上LLM,它就能帮你总结和组织答案了。
import requests
def ask_knowledge_base(question: str) -> str: """查询知识库并让LLM生成答案""" # 检索相关片段 results = query_knowledge(question, top_k=3)
# 构建上下文 context = "\n\n".join([ f"【来自 {r['title']}】\n{r['content']}" for r in results ])
# 让LLM生成答案 prompt = f"""基于以下知识库内容回答问题:
{context}
问题:{question}
如果知识库中没有相关信息,请明确说明。"""
# 调用本地Ollama response = requests.post("http://localhost:11434/api/generate", json={ "model": "qwen2.5:7b", "prompt": prompt, "stream": False })
return response.json()["response"]
# 试试answer = ask_knowledge_base("Docker容器的端口映射怎么做?")print(answer)实际使用体验
这套东西我用了快两个月。说一下真实感受:
好的部分:
- 确实比手动翻文件夹快一百倍
- 很多技术问题能直接找到之前记录过的解决方案
- 数据完全在本地,不用担心隐私
不好的部分:
- 模型是7B量化版,复杂问题的回答质量一般
- 如果知识库里的内容不够全面,LLM会尝试”自己编”,需要提醒它”没有就说不清楚”
- Embedding模型对技术代码的向量效果不如自然语言好
总结
搭一个个人AI知识库并不需要多复杂的技术栈。核心就是四步:读取文档 → 切分 → 向量化 → 查询。再加一个LLM让它能对话。
关键不是技术,是你得有足够的、高质量的知识内容。否则知识库就是空的,什么都检索不到。
所以真正的问题不是”怎么搭”,而是”你平时有没有在积累知识”。
你搭过个人知识库吗?用的什么方案?