一、Chatbot 作用
在当今的内容网站和个人博客中,一个能主动回答访客问题、提供导航帮助、甚至辅助销售的 Chatbot(智能对话助手) 已成为提升用户体验的重要工具。
它可以:
- 自动回答常见问题,减少访客流失;
- 引导用户找到相关内容或产品;
- 展示网站的智能化与互动性;
- 收集用户需求,帮助优化内容与产品。
在日常工作中,我对这项功能的依赖度正不断提升,它已成为提升效率的实用工具,具体应用场景如下:
- 面对各类工具的使用需求时,若无暇逐字研读冗长的使用文档,直接借助 chatbot 功能即可快速解决问题 —— 无论是让它直观演示工具操作步骤、针对性解答使用中遇到的故障,还是精准定位到文档里与需求匹配的核心章节,都能大幅节省摸索时间。
- 进行文档检索工作时,传统的精确关键字匹配常常存在局限:要么因关键词表述偏差错过关键信息,要么检索结果冗余繁杂。此时,运用 RAG 技术就能有效突破这一痛点,它能基于语义理解精准捕捉需求核心,从海量文档中快速筛选出高相关性内容,显著提升检索效率与准确性。
并不是所有网站都适合或需要添加 Chatbot:
- 内容极少或结构极简单的网站,如果网站只有一两页、没有复杂导航或可搜索内容,那么 Chatbot 的作用有限。
此时访客的主要操作是浏览或点击按钮,直接放置清晰的 CTA(Call to Action,如“立即联系我”、“查看项目”)会比聊天框更高效。 - 对内容输出高度受控的网站,如:政府官网、金融、医疗、法律服务类网站。这些网站对回答的准确性和合规性要求极高,而 Chatbot 的生成式特性可能:产生“幻觉”(编造内容)、引发法律或监管风险、误导用户产生错误理解。可以选择使用 知识问答检索系统(FAQ 搜索) 或 静态问答模板,在后台人工维护。
二、实现 Chatbot 的几种方式
在网站中集成 Chatbot 有多种实现方案,取决于你的技术栈和目标。
方式一:使用第三方工具(零代码)
如果你不想写代码,可以直接使用以下服务:
- Chatbase(https://www.chatbase.co)
- Flowise(开源)
- OpenAI GPT Assistant API(可通过低代码平台集成)
这些平台通常允许你:
- 上传你的网站内容(或提供 RSS/链接爬取);
- 自定义助手的角色与回答语气;
- 生成一个 JavaScript 嵌入脚本;
- 将脚本插入你的网站页面,即可出现 Chatbot 浮窗。
示例代码:
<script src="https://cdn.chatbase.co/chatbase.js"
chatbot-id="your-chatbot-id"
domain="https://lvmaoya.cn"
defer>
</script>只需将上述代码放入你网站的 <body> 或 <footer> 区域,Chatbot 就能在所有页面中生效。
方式二:使用自己写代码实现
三、自己动手实现(基于目前这个网站技术架构:Nuxt3 + Springboot3)
第一步:先来调用大模型,实现一个对话的接口
相关依赖:
<!-- spring-ai -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M5</version>
</dependency>在 application.yml 中配置模型与基础参数:
spring:
ai:
openai:
api-key: 你的对应平台的api-key
base-url: https://api.deepseek.com
chat:
options:
model: deepseek-chat相关实现代码:
@PostMapping("/chat/min/stream")
public SseEmitter chatMinStream(@RequestBody ChatBotRequest request) {
if (request == null || StringUtils.isBlank(request.getMessage())) {
SseEmitter bad = new SseEmitter(0L);
try { bad.send(SseEmitter.event().name("error").data("消息内容不能为空")); } catch (Exception ignored) {}
bad.complete();
return bad;
}
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
try {
List<Message> history = new ArrayList<>();
history.add(new UserMessage(request.getMessage()));
chatModel.stream(new Prompt(history)).subscribe(
chunk -> {
String delta = chunk.getResult().getOutput().getContent();
if (delta != null && !delta.isEmpty()) {
try { emitter.send(SseEmitter.event().name("message").data(delta)); }
catch (Exception ignored) {}
}
},
error -> {
try { emitter.send(SseEmitter.event().name("error").data(error.getMessage())); }
catch (Exception ignored) {}
emitter.completeWithError(error);
},
() -> {
try { emitter.send(SseEmitter.event().name("done").data("[DONE]")); }
catch (Exception ignored) {}
emitter.complete();
}
);
} catch (Exception e) {
try { emitter.send(SseEmitter.event().name("error").data(e.getMessage())); }
catch (Exception ignored) {}
emitter.completeWithError(e);
}
return emitter;
}至此一个简单的基于SSE的对话接口就完成了。
如果希望其能够有记忆,可以将最近的最近的N条对话history给存起来,下次对话时带上就好了。
第二步:如何向大模型灌入你的私有知识?了解更多
可以有两种方式:模型微调、RAG检索增强生成。
微调是指在预训练大模型的基础上,用自定义的数据对模型进行二次训练,使模型在特定领域或任务上表现更好。
简单说,就是让大模型“带着你的知识和风格再学一遍”,从而更懂你、说你想要的内容,成本较高,所以我们选用了RAG。
基于RAG的方式其实也是通过我们把用户的message与我们的后台文章进行一个语义的匹配,然后再将匹配到的文章片段信息作为prompt给到大模型。不用rag,我们可以通过sql查询的方式进行强匹配,使用体验不好。
RAG的整体流程:用户问题 → 向量化 → 检索相似内容 → 构造提示(Prompt) → 模型生成答案
这里就需要用到了 嵌入模型和向量数据库。考虑到我的服务器比较拉跨就使用了云服务商:智普的嵌入模型,数据库自己跑的。如果机器允许的话可以自己部署用到的相关模型。这里的向量库我使用的是Milvus
相关代码带你了解RAG流程:
from openai import OpenAI
from chromadb import Client
from chromadb.config import Settings
import numpy as np
client = OpenAI(api_key="your-api-key")
# 初始化向量数据库
chroma = Client(Settings(persist_directory="./chroma_db"))
collection = chroma.create_collection("docs")
# 向量化并入库
texts = [
"退货须在30天内凭订单号申请",
"特价商品不支持退货"
]
for t in texts:
emb = client.embeddings.create(model="text-embedding-3-large", input=t).data[0].embedding
collection.add(documents=[t], embeddings=[emb])
# 用户提问
query = "我买的折扣商品可以退货吗?"
query_emb = client.embeddings.create(model="text-embedding-3-large", input=query).data[0].embedding
# 检索相似内容
results = collection.query(query_embeddings=[query_emb], n_results=2)
context = "\n".join(results["documents"][0])
# 拼接 Prompt
prompt = f"根据以下信息回答:\n{context}\n\n问题:{query}"
# 生成答案
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
print(response.choices[0].message.content)第三步:优化prompt是非常关键的一步
例如:
