传统客服机器人是「把资料全塞进提示词里让大模型自己找」,资料一多就贵、就慢、还会答歪。 这套系统把「找」和「说」拆成两步,各用最合适的模型。
把退换货政策、物流说明、产品参数等资料导入后台,系统自动切块、向量化,写进 Qdrant。
一次性动作顾客一问,问题先变成向量,直接去 Qdrant 找最相关的几段资料——不做全表扫描,资料再多也快。
毫秒级找到资料才交给大模型组织成通顺回答;没找到就直接回兜底话术并引导转人工,不浪费模型调用。
省 token从知识库入库、问答、到人工接待与数据回看,一条链路都在后台里闭环。
整个过程在一次请求里完成,前端通过 SSE 边收边显示。
聊天页或嵌入组件提交问题,落到 /api/chat.php
是否启用、域名是否在白名单、当日提问是否超限
交给向量模型,把问题变成一串数字
按渠道设定的知识库分类过滤,取回最相关的几个分块
回一句「没找到准确答案」并引导转人工,不调用大模型
把资料和问题拼成提示词,流式调用对话模型
SSE 流式输出,回答完连同来源一起落库
两边是同一套数据的两面,顾客在同一个窗口里从 AI 平滑过渡到真人,不需要跳转。
一个聊天窗口,或者右下角的悬浮气泡。
六个页面,覆盖从入库到接待的全过程。
一个会话在任何时刻只处于一种状态,顾客再开口时状态会自动流转,不需要人工干预。
纯原生实现,没有框架、没有构建步骤、没有 Composer 依赖 —— 丢到任何支持 PHP 8 的空间就能跑。
| 层次 | 技术选型 | 说明 |
|---|---|---|
| 前端 | 原生 HTML / CSS / JavaScript | 无框架、无打包。顾客端聊天页 + 可嵌入任意网站的悬浮组件 |
| 后端 | PHP 8 原生,App\ 命名空间自动加载 |
分层清晰:数据层 / 客户端 / 检索 / 生成 / 鉴权,各管一件事 |
| 业务数据 | SQLite(PDO) | 零配置、免运维。文档、分块、渠道、会话、配置全在这里 |
| 向量库 | Qdrant(REST API) | 知识库分块的向量与其原文都存这里,提问时直接检索 |
| 模型 | 任意 OpenAI 兼容接口 | 向量模型与对话模型可分别配不同厂商,互不影响 |
| 流式输出 | SSE(Server-Sent Events) | 回答边生成边推送;部署时需关闭 nginx 缓冲,否则会「转圈半天然后整段出现」 |
| 安全 | 密钥加密 / CSRF / 同源校验 / 上传校验 | API 密钥以 AES-256-CBC 加密入库;后台写操作校验 CSRF 与来源 |
本地跑起来只需两条命令;正式上线有四个容易踩的点,列在最前面。
pdo_sqlite、sqlite3、curl、openssl、mbstringdata/、logs/、public/uploads/public/,不要指向项目根目录fastcgi_buffering off;),否则流式回答会变成整段弹出data/ logs/ config/ src/ 被直接访问,上传目录禁止执行脚本http_proxy 环境变量会让「访问本机向量库」的请求被强行送进代理,表现为「配置全对但连不上」——
系统默认直连并把这一点做成了设置项。以下命令在项目根目录执行(示例中的 PHP 路径请换成你自己的)。
# 1) 初始化数据库(加 --demo 会灌一份演示知识库)
php cli/init.php --demo
# 2) 启动服务(默认监听本机;加 --lan 允许局域网访问)
php cli/serve.php 8080
php cli/serve.php --lan
# 3) 打开后台 → 系统设置,填向量库地址与两个模型,点「测试」确认连通
# 后台: http://127.0.0.1:8080/admin/
# 连通性自检(向量库 / 向量模型 / 对话模型)
php cli/ingest.php --check
# 导入待处理文档(大库推荐走命令行,比后台点按钮快得多)
php cli/ingest.php --all
# 从文件或目录批量导入
php cli/ingest.php --file=资料.md --title="退换货政策" --category=售后
php cli/ingest.php --dir=./docs
# 换了模型或知识库后:全量重建 + 重新标定阈值(两步都要做)
php cli/ingest.php --rebuild
php cli/calibrate.php --apply
<!-- 右下角悬浮客服气泡,一行搞定 -->
<script src="https://ai.36ysk.com/widget.js" data-aikefu="6be0e77c1e8f" data-color="#2563eb" async></script>
最常见的原因是相似度阈值没标定。不同向量模型的分数基线差别很大,阈值定太高就会把正常提问也判成「查不到」。
到「知识库」页用内置的检索测试压一个真实问题,看它给的匹配度;再跑一次阈值标定工具按你的数据算一次建议值。
另外确认资料已经导入完成(文档状态为「已就绪」)——只上传不导入,是搜不到的。
这是流式输出与短轮询并发导致的重复渲染,已经修复(前端按消息 id 去重)。如果还遇到,先 Ctrl+F5 强制刷新,清掉浏览器缓存的旧脚本。
先 Ctrl+F5 强刷(样式表有缓存时改动不会生效)。仍不对就说明是布局问题,系统带了一个布局体检脚本,会用多种窗口尺寸逐个检查横向溢出与遮挡,并直接指出是哪个元素出问题。
浏览器规定「用户没有交互过的页面不许播放声音」,这是安全策略绕不过去。点一下页面任意位置(比如点某个会话)就会解锁,之后一直正常。
其次检查右上角是不是被自己点成静音了;再检查标签页有没有被浏览器静音(右键标签页可看)。
① 确认后台「人工客服」页是开着的(任意后台页面开着都算在线);② 检查「系统设置 → 人工客服」的总开关; ③ 检查该客服渠道的「转人工方式」是不是设成了「只跳外部链接」。
会,但很少。导入知识库时消耗向量模型;顾客提问时每次都消耗向量模型,但只有检索到资料才调用对话模型 —— 答不上来的时候直接走兜底话术,不产生对话费用。顾客在跟真人客服聊天时,两个模型都不调用。
想进一步压成本,把「每次带几段资料」调小最有效。
三件事:全量重建索引(按新模型的维度重建集合并重新导入)→ 重新标定阈值(分数基线变了)→ 拿几个真实问题在「检索测试」里验证一遍。本地文档与分块都保留,重建不会丢数据。
能用。启动时加 --lan 让服务监听所有网卡,启动器会列出可访问的局域网地址。
务必用局域网地址登录后台:客服链接与嵌入代码是按「你当前访问用的域名」生成的,用本机地址登录会生成打不开的链接。
业务数据都在 SQLite 数据库里,向量在 Qdrant。备份只需复制数据库文件与密钥文件即可; 向量可以随时用一条命令从本地文档重新生成,所以只要数据库在手,知识库就能完整重建。