PrivateGPT 文档问答¶
为什么要学 PrivateGPT¶
PrivateGPT 是一个专注于隐私的文档问答系统,所有处理100%在本地完成,不需要联网。它特别适合处理敏感文档(法律合同、医疗记录、财务报告等),因为数据永远不会离开你的机器。PrivateGPT 提供了 API 和 UI,支持多种文档格式的摄入和基于 RAG 的问答。
核心概念¶
| 概念 | 白话解释 | 用途 |
|---|---|---|
| Ingestion | 文档摄入 | 将文档解析、切片、嵌入 |
| RAG Pipeline | 检索增强生成 | 先搜索相关文档片段,再生成回答 |
| Completion Mode | 补全模式 | 纯 LLM 对话,不使用文档 |
| Chunk | 文本块 | 文档被切分的最小单位 |
| Source Attribution | 来源归属 | 回答时标注引用的文档和位置 |
| Profile | 配置档 | 预设的后端和参数组合 |
安装配置¶
环境准备¶
# 需要 Python 3.11+
python --version
# 克隆项目
git clone https://github.com/zylon-ai/private-gpt.git
cd private-gpt
# 使用 poetry 安装
pip install poetry
poetry install --extras "ui llms-ollama embeddings-ollama vector-stores-qdrant"
配置文件¶
# settings.yaml
server:
env_name: local
port: 8001
llm:
mode: ollama
max_new_tokens: 512
context_window: 3900
temperature: 0.1
ollama:
llm_model: llama3
embedding_model: nomic-embed-text
api_base: http://localhost:11434
embedding:
mode: ollama
embed_dim: 768
vectorstore:
database: qdrant
qdrant:
path: ./local_data/qdrant
data:
local_data_folder: ./local_data
ui:
enabled: true
path: /
快速启动¶
# 确保 Ollama 在运行
ollama serve &
ollama pull llama3
ollama pull nomic-embed-text
# 启动 PrivateGPT
poetry run python -m private_gpt
# 访问 UI: http://localhost:8001
# API docs: http://localhost:8001/docs
Docker 部署¶
version: '3.8'
services:
private-gpt:
build: .
ports:
- "8001:8001"
volumes:
- ./local_data:/app/local_data
- ./settings.yaml:/app/settings.yaml
environment:
- PGPT_PROFILES=ollama
depends_on:
- ollama
ollama:
image: ollama/ollama
volumes:
- ollama-data:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
volumes:
ollama-data:
快速上手¶
通过 UI 使用¶
- 打开
http://localhost:8001 - 在左侧面板上传文档
- 等待 ingestion 完成(状态变为绿色)
- 在右侧对话框中提问
- 回答会附带来源文档引用
API 文档摄入¶
# 上传文档
curl -X POST http://localhost:8001/v1/ingest/file \
-F "file=@report.pdf"
# 上传文本
curl -X POST http://localhost:8001/v1/ingest/text \
-H "Content-Type: application/json" \
-d '{
"file_name": "notes.txt",
"text": "这里是文档内容..."
}'
# 查看已摄入的文档
curl http://localhost:8001/v1/ingest/list
API 问答¶
import requests
BASE = "http://localhost:8001/v1"
# 带上下文的问答(使用文档)
response = requests.post(f"{BASE}/chat/completions", json={
"messages": [
{"role": "user", "content": "这份报告的主要结论是什么?"}
],
"use_context": True,
"context_filter": {
"docs_ids": ["doc-id-1", "doc-id-2"] # 可选:限定搜索范围
},
"include_sources": True
})
data = response.json()
print(data["choices"][0]["message"]["content"])
for source in data["choices"][0]["sources"]:
print(f" 来源: {source['document']['doc_metadata']['file_name']}")
进阶用法¶
批量文档摄入¶
import os
import requests
from pathlib import Path
INGEST_URL = "http://localhost:8001/v1/ingest/file"
docs_dir = Path("./documents")
supported = {".pdf", ".docx", ".txt", ".md", ".csv", ".html"}
for file_path in docs_dir.rglob("*"):
if file_path.suffix.lower() in supported:
print(f"Ingesting: {file_path.name}")
with open(file_path, "rb") as f:
response = requests.post(
INGEST_URL,
files={"file": (file_path.name, f)}
)
if response.status_code == 200:
print(f" OK: {response.json()}")
else:
print(f" Error: {response.status_code}")
自定义切片策略¶
# settings.yaml
ingestion:
chunk_size: 500
chunk_overlap: 100
# 针对不同文件类型的处理
parsers:
pdf:
parser: "pymupdf" # 或 "unstructured"
docx:
parser: "docx2txt"
多租户隔离¶
# 使用 context_filter 实现文档隔离
# 每个租户上传时打标签
# 上传时(假设有元数据支持)
response = requests.post(f"{BASE}/v1/ingest/file",
files={"file": open("doc.pdf", "rb")},
data={"metadata": '{"tenant": "team-a"}'}
)
# 查询时过滤
response = requests.post(f"{BASE}/v1/chat/completions", json={
"messages": [{"role": "user", "content": "问题"}],
"use_context": True,
"context_filter": {"docs_ids": team_a_doc_ids}
})
性能调优¶
# settings.yaml
llm:
context_window: 3900 # 根据模型实际支持调整
max_new_tokens: 1024 # 回答长度上限
temperature: 0.1 # 低温度提高准确性
embedding:
embed_dim: 768 # 匹配所选模型的维度
rag:
similarity_top_k: 5 # 检索的片段数量
similarity_value: 0.7 # 最低相似度阈值
rerank:
enabled: true
model: "cross-encoder/ms-marco-MiniLM-L-6-v2"
top_n: 3
常见问题¶
Q: 摄入大量 PDF 很慢怎么办?¶
- 使用
pymupdf替代unstructured解析器(更快) - 减少
chunk_overlap值 - 对特别大的文档先提取关键章节
Q: 回答质量不高?¶
- 增加
similarity_top_k(从 3 增加到 5-8) - 启用 rerank 功能
- 优化文档切片大小(技术文档 500-800,一般文档 300-500)
- 换更好的 Embedding 模型
Q: 如何删除已摄入的文档?¶
Q: 支持哪些文档格式?¶
PDF、DOCX、TXT、Markdown、CSV、HTML、EPUB、JSON 等。通过 Unstructured 解析器还支持 PPTX、XLSX 等。
Q: 与 AnythingLLM 的区别?¶
- PrivateGPT:更注重隐私和 API-first 设计,适合集成到现有系统
- AnythingLLM:UI 更丰富,多用户管理更完善,适合直接给终端用户使用
参考资源¶
- GitHub:https://github.com/zylon-ai/private-gpt
- 文档:https://docs.privategpt.dev/
- API Reference:http://localhost:8001/docs(启动后)
- 配置参考:https://docs.privategpt.dev/manual/settings
- Discord:https://discord.gg/bK6mRVpErU