智能客服已经是现代企业的标配——但购买成熟的SaaS方案动辄年费数万甚至数十万,对于中小团队来说成本太高。好在,借助开源工具和LLM(大语言模型),你完全可以用很低的成本搭建一个功能强大的智能客服机器人。
本文使用纯开源技术栈,手把手带你从零实现。
我们的智能客服机器人采用经典 RAG(检索增强生成)架构:
用户提问
│
▼
┌─────────────────┐
│ 前端对话界面 │ ← Web / 小程序 / 钉钉 / 企微
└────────┬────────┘
│
▼
┌─────────────────┐
│ API 网关 │ ← FastAPI / Flask
└────────┬────────┘
│
┌────┴────┐
│ │
▼ ▼
┌────────┐ ┌────────────┐
│ LLM │ │ 向量数据库 │ ← ChromaDB / Qdrant / Milvus
│ 模型 │ │ (知识库) │
└────────┘ └────────────┘
核心组件说明:
环境要求:
安装依赖:
pip install langchain langchain-community chromadb fastapi uvicorn
pip install openai # 如果使用OpenAI兼容API
# 或使用开源模型
pip install llama-cpp-python # 本地运行GGUF模型
知识库是智能客服的大脑。把你企业的常见问题(FAQ)、产品文档、操作手册整理成文档,存入向量数据库。
创建一个 knowledge_base/ 目录,放入MD或TXT格式的文档。例如:
knowledge_base/
├── 常见问题.md
├── 退款政策.md
├── 产品使用指南.md
└── 技术支持联系.md
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 1. 加载文档
loader = DirectoryLoader("knowledge_base/", glob="**/*.md")
documents = loader.load()
# 2. 文档分块
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = text_splitter.split_documents(documents)
# 3. 生成向量并存储
embeddings = OpenAIEmbeddings() # 或使用开源嵌入模型
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db"
)
vectorstore.persist()
print(f"知识库已构建完成,共 {len(chunks)} 个文档片段")
使用LangChain的检索问答链实现核心问答功能:
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
# 加载已构建的向量数据库
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(
persist_directory="./chroma_db",
embedding_function=embeddings
)
# 自定义提示词模板
prompt_template = """你是一个专业的客服助手。请基于以下已知信息回答用户的问题。
如果已知信息不足以回答问题,请说"我无法从现有知识库中找到答案",
不要编造信息。
已知信息:
{context}
用户问题:{question}
请用友好的语气回答,保持简洁有条理。如果涉及操作步骤,请用编号列出。
回答:"""
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0),
chain_type="stuff",
retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
chain_type_kwargs={
"prompt": PromptTemplate(
template=prompt_template,
input_variables=["context", "question"]
)
}
)
# 测试
response = qa_chain.run("如何申请退款?")
print(response)
用 FastAPI 包装成 HTTP 接口:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uvicorn
app = FastAPI(title="智能客服API")
class Query(BaseModel):
question: str
session_id: str | None = None
class Response(BaseModel):
answer: str
sources: list[str] = []
# 会话历史存储(生产环境请用Redis)
sessions = {}
@app.post("/api/chat", response_model=Response)
async def chat(query: Query):
try:
# 获取或创建会话历史
history = sessions.get(query.session_id, [])
# 调用问答引擎
result = qa_chain.invoke({
"query": query.question,
"chat_history": history
})
# 更新会话历史
history.append((query.question, result["result"]))
if query.session_id:
sessions[query.session_id] = history[-10:] # 保留最近10轮
return Response(
answer=result["result"],
sources=[doc.metadata.get("source", "") for doc in result["source_documents"]]
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
用纯HTML/JS快速搭建一个对话界面(可直接嵌入到现有网站):
<!-- chatbot-widget.html -->
<div id="chatbot-widget">
<div id="chatbot-header">
🤖 智能客服
<button onclick="toggleChat()">×</button>
</div>
<div id="chatbot-messages"></div>
<div id="chatbot-input">
<input type="text" id="chat-input" placeholder="输入您的问题..." />
<button onclick="sendMessage()">发送</button>
</div>
</div>
<script>
const sessionId = 'session_' + Date.now();
async function sendMessage() {
const input = document.getElementById('chat-input');
const msg = input.value.trim();
if (!msg) return;
addMessage(msg, 'user');
input.value = '';
const res = await fetch('/api/chat', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ question: msg, session_id: sessionId })
});
const data = await res.json();
addMessage(data.answer, 'bot');
}
function addMessage(text, role) {
const container = document.getElementById('chatbot-messages');
const div = document.createElement('div');
div.className = 'message ' + role;
div.textContent = text;
container.appendChild(div);
container.scrollTop = container.scrollHeight;
}
</script>
本文搭建的智能客服机器人使用了纯开源技术栈,虽然功能上可能无法100%对标销售SaaS产品,但对于大多数中小团队来说已经足够使用。更重要的是——数据完全掌握在自己手中,没有第三方泄露风险。
从知识库构建,到RAG引擎,再到API和前端,整套方案可在一两天内完成搭建。现在就开始吧!