基于Langchain实现带文档引用的聊天并自托管模型的可行性与方法
基于LangChain搭建带来源标注的自托管文档聊天系统方案
需求需求可行性
完全可行。LangChain原生支持自托管大模型集成,同时内置了文档来源追踪与标注能力,无需依赖OpenAI、Anthropic等专有服务即可实现需求。
具体实现步骤
1. 部署自托管大模型
- 选择开源模型:根据硬件配置挑选合适的模型,比如Llama 2、Mistral、Qwen等。7B/13B参数的小模型可在消费级GPU(如RTX 3090/4090)上运行,也可使用CPU(速度较慢)。
- 快速部署方案:用Ollama部署最简便,无需复杂配置:
- 安装Ollama后,运行命令启动模型:
ollama run llama2 - 模型会自动在
http://localhost:11434提供OpenAI兼容的API接口,验证可用:curl http://localhost:11434/v1/models
- 安装Ollama后,运行命令启动模型:
- 可选部署方式:如果需要更高性能,可使用vLLM或FastChat部署,同样提供OpenAI兼容API。
2. 文档处理与向量存储
- 加载文档:用LangChain的加载器读取指定文档,支持PDF、TXT、Markdown等格式:
from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("your_target_document.pdf") raw_docs = loader.load() - 分割文档:将长文档拆分为模型可处理的小片段,避免上下文溢出:
from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=50) split_docs = text_splitter.split_documents(raw_docs) - 生成嵌入向量:用开源嵌入模型自托管生成向量,避免依赖第三方服务:
from langchain.embeddings import HuggingFaceEmbeddings embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-base-en-v1.5") - 存储向量:将文档片段和向量存入自托管向量数据库(如Chroma、FAISS):
from langchain.vectorstores import Chroma db = Chroma.from_documents(split_docs, embeddings, persist_directory="./local_chroma_db") db.persist()
3. 构建带来源标注的聊天链
- 对接自托管LLM:用LangChain的
ChatOpenAI类适配Ollama的API:from langchain.chat_models import ChatOpenAI llm = ChatOpenAI( model_name="llama2", openai_api_base="http://localhost:11434/v1", openai_api_key="placeholder", # Ollama无需实际密钥,填任意值即可 temperature=0.1 # 降低温度提升回答准确性 ) - 创建检索-回答链:使用
RetrievalQAWithSourcesChain自动关联回答与来源文档:from langchain.chains import RetrievalQAWithSourcesChain chain = RetrievalQAWithSourcesChain.from_chain_type( llm=llm, chain_type="stuff", retriever=db.as_retriever(search_kwargs={"k": 3}), # 检索前3个最相关的文档片段 return_source_documents=True ) - 测试聊天功能:
query = "请解释文档中的XX概念" result = chain({"question": query}, return_only_outputs=True) print("回答:", result["answer"]) print("来源:", result["sources"])
4. 自定义优化
- 调整来源格式:如果默认的来源展示不符合需求,可自定义提示词模板,指定来源标注的格式(比如
[文档名:页码]):from langchain.prompts import PromptTemplate template = """使用以下上下文回答问题,最后务必用【来源:{sources}】标注信息来源: {context} 问题:{question} 回答:""" prompt = PromptTemplate(template=template, input_variables=["context", "question", "sources"]) # 将自定义prompt传入链中 - 性能优化:使用量化模型(如GGUF格式)减少显存占用,或用vLLM提升并发处理能力;调整检索的
k值平衡相关性和回复长度。
内容的提问来源于stack exchange,提问作者tobias
相关产品推荐
相关产品推荐

