English | 中文
开源的 AI 客服系统:AI + 人工一体、可私有化部署、可配置、可观测。
适合把「官网右下角客服小窗」与「客服工作台」一起落地的团队。
官网首页(核心能力模块)
客服小窗
人工客服模式
|
AI 客服模式
|
access_token,读/发消息与 WebSocket 须携带令牌,防止仅凭会话 ID 越权访问.env 可配天数)/ 快捷搜索 FAQsources_used(知识库 / 大模型 / 联网)metadata / Open Graph / JSON-LD / sitemap.xml / robots.txt,便于搜索引擎收录与社交分享SERPER_MCP_URL)或直连 API(SERPER_API_KEY)AI-CS/
├── backend/ # Go 后端:API、WebSocket、AI、RAG
│ ├── controller/ # HTTP 控制器
│ ├── service/ # 业务逻辑(会话、消息、知识库、AI…)
│ ├── repository/ # 数据访问
│ ├── models/ # 数据模型
│ ├── infra/ # DB、Milvus、ip2region、存储
│ ├── websocket/ # 实时消息与 Redis 广播
│ ├── router/ # 路由注册
│ ├── data/ # ip2region xdb(可选,见 data/README.md)
│ └── main.go
├── frontend/ # Next.js:官网、访客小窗、客服工作台
│ ├── app/ # 页面路由(/、/chat、/agent/*)
│ ├── components/ # UI 组件
│ ├── features/ # 按领域划分的 API / hooks
│ └── public/widget.js # 可嵌入站点的脚本小窗
├── doc/ # 项目文档与 CHANGELOG
├── scripts/ # 辅助脚本(如下载 ip2region xdb)
├── assets/readme/ # README 截图资源
├── docker-compose.yml # 本地构建部署
├── docker-compose.prod.yml # 预构建镜像部署
├── docker-compose.milvus.yml # Milvus 相关(按需)
└── .env.example # 环境变量模板(复制为 .env)
/.env)统一配置真源:只维护项目根目录
/.env。Docker 与本地启动都读这一份。
初始化:复制/.env.example为/.env并填写必填项。
git clone https://github.com/2930134478/AI-CS.git
cd AI-CS
cp .env.example .env
至少要改(必填):
MYSQL_ROOT_PASSWORD、DB_PASSWORDADMIN_PASSWORDENCRYPTION_KEY(64 位 hex)生成 ENCRYPTION_KEY:
# Linux/Mac
openssl rand -hex 32
# Windows PowerShell
-join ((48..57) + (97..102) | Get-Random -Count 64 | ForEach-Object {[char]$_})
docker-compose -f docker-compose.prod.yml up -d
admin(或 .env 中 ADMIN_USERNAME).env 中 ADMIN_PASSWORD生产部署提示:前端生产镜像走同域
/api/*,需外层 Nginx/Caddy 将/api反向代理到后端,并转发X-User-Id、X-Conversation-Token等自定义请求头。本地npm run dev时由 Next.js rewrites 自动代理。
ADMIN_PASSWORD 仅在首次创建管理员时生效;数据库里已有管理员后,重启服务不会覆盖其密码。admin 账号密码admin 账号agent 用户时,系统会自动把其名下 AI 配置转移给当前管理员,避免配置丢失或无人维护。3000,后端对外 18080.env 里改 FRONTEND_PORT / BACKEND_PORT说明:预构建镜像在某些静态资源/图片路径场景可能与端口强绑定(历史兼容原因)。如果你需要彻底自定义端口并确保所有资源路径一致,建议用下面的「方式 B 本地构建」。
git clone https://github.com/2930134478/AI-CS.git
cd AI-CS
cp .env.example .env
docker-compose up -d --build
环境要求:
MySQL 8.0+
git clone https://github.com/2930134478/AI-CS.git
cd AI-CS
cp .env.example .env
# 1) 后端
cd backend
go mod tidy
go run main.go
# 2) 前端(新开终端)
cd ../frontend
npm install
npm run dev
/.env)下面表格以
/.env.example为准,帮助你快速判断「必填/可选/什么时候需要填」。
| 变量 | 用途 | 是否必填 | 默认值(示例) | 示例 |
|---|---|---|---|---|
APP_PROFILE |
部署画像(docker/local) |
否 | docker |
local |
SERVER_HOST |
后端监听地址 | 是 | 0.0.0.0 |
127.0.0.1 |
SERVER_PORT |
后端容器内端口 | 是 | 8080 |
8080 |
GIN_MODE |
后端模式 | 建议 | release |
debug |
SYSTEM_LOG_MIN_LEVEL |
结构化日志最低落库级别(system_logs) |
否 | info |
warn 可减少成功类写入;none 关闭落库;客服端「日志中心」可改并持久化,覆盖本项直至恢复 |
DB_HOST |
后端数据库地址 | 是 | mysql |
localhost |
DB_PORT |
后端数据库端口 | 是 | 3306 |
3306 |
DB_USER |
数据库用户名 | 是 | ai_cs_user |
root |
DB_PASSWORD |
数据库密码 | 是 | 无 | StrongPwd |
DB_NAME |
数据库名 | 是 | ai_cs |
ai_cs |
MYSQL_ROOT_PASSWORD |
MySQL root 密码(compose) | 是(Docker) | 无 | RootPwd |
MYSQL_PORT |
MySQL 对外端口(compose) | 否 | 3306 |
13306 |
ADMIN_USERNAME |
默认管理员用户名 | 否 | admin |
admin |
ADMIN_PASSWORD |
默认管理员密码 | 是 | 无 | AdminPwd |
ENCRYPTION_KEY |
后端加密密钥(64位 hex) | 是 | 无 | openssl rand -hex 32 |
REDIS_URL |
Redis 连接串(启用跨实例 WS 广播) | 可选(多实例推荐) | 空 | redis://:pwd@redis:6379/0 |
REDIS_ADDR |
Redis 地址(与 REDIS_URL 二选一) |
可选 | 空 | redis:6379 |
REDIS_PASSWORD |
Redis 密码(使用 REDIS_ADDR 时) |
可选 | 空 | StrongRedisPwd |
REDIS_DB |
Redis DB(使用 REDIS_ADDR 时) |
可选 | 0 |
0 |
REDIS_WS_CHANNEL |
分布式 WS 事件频道名 | 可选 | ai_cs:ws_events |
ai_cs:ws_events |
BACKEND_PORT |
后端映射到宿主机端口 | 否 | 18080 |
28080 |
FRONTEND_PORT |
前端映射到宿主机端口 | 否 | 3000 |
13000 |
MILVUS_HOST |
向量库地址 | 可选(启用 RAG) | milvus-standalone |
localhost |
MILVUS_PORT |
向量库端口 | 可选(启用 RAG) | 19530 |
19530 |
MILVUS_USERNAME |
Milvus 用户名 | 可选 | 空 | user |
MILVUS_PASSWORD |
Milvus 密码 | 可选 | 空 | pass |
MILVUS_DISABLED |
禁用向量库(不连接) | 否 | false |
true |
VECTOR_STORE_DISABLED |
同上(兼容开关) | 否 | false |
true |
MILVUS_REQUIRED |
强依赖向量库(失败即退出) | 否 | false |
true |
RAG_MIN_SCORE |
RAG 向量检索最低相似度(0~1) | 否 | 0.22 |
分段场景可试 0.2~0.35 |
AUTO_CLOSE_CONVERSATION_DAYS |
自动关闭 N 天未活跃 open 会话(0=关闭) | 否 | 7 |
也可在 设置 → 会话维护 配置 |
OFFLINE_EMAIL_ENABLED |
访客离线邮件推送总开关 | 否 | false |
true |
OFFLINE_EMAIL_DELAY_SECONDS |
离线邮件延迟秒数 | 否 | 60 |
30 |
SMTP_HOST / SMTP_PORT |
离线邮件 SMTP 地址与端口 | 可选 | 空 / 465 |
优先在 设置页 配置 |
SMTP_USER / SMTP_PASSWORD |
SMTP 账号与密码 | 可选 | 空 | 云厂商 SMTP |
SMTP_FROM_EMAIL / SMTP_FROM_NAME |
发件人邮箱与显示名 | 可选 | 空 | noreply@example.com |
SERPER_MCP_URL |
联网搜索 MCP 地址 | 可选(启用联网) | 空 | http://host:3000/sse |
SERPER_API_KEY |
联网搜索 API Key | 可选(启用联网) | 空 | xxxxx |
NEXT_PUBLIC_SITE_URL |
站点对外绝对地址(用于 SEO) | 否 | 空(默认 demo 域名) | https://www.example.com |
NEXT_PUBLIC_API_BASE_URL |
前端公开 API 地址 | 建议 | http://localhost:18080 |
https://api.example.com |
NEXT_PUBLIC_BACKEND_HOST |
前端 dev 代理目标 host | 否 | localhost |
127.0.0.1 |
NEXT_PUBLIC_BACKEND_PORT |
前端 dev 代理目标 port | 否 | 8080 |
18080 |
NEXT_PUBLIC_MATOMO_CONTAINER_URL |
Matomo 脚本地址 | 可选 | 空 | https://.../container.js |
BACKEND_IMAGE |
预构建后端镜像(prod compose) | 是(prod) | 537yaha/ai-cs-backend:latest |
your/backend:tag |
FRONTEND_IMAGE |
预构建前端镜像(prod compose) | 是(prod) | 537yaha/ai-cs-frontend:latest |
your/frontend:tag |
| 用途 | 配置位置 | 接口 |
|---|---|---|
| AI 对话(大模型回复) | 设置 → AI 配置 | OpenAI 兼容 Chat Completions(如 …/v1/chat/completions) |
| 向量化 / RAG 检索 | 设置 → 知识库向量模型 | OpenAI 兼容 Embeddings(如 …/v1/embeddings) |
.env 里 MILVUS_DISABLED=true(或 VECTOR_STORE_DISABLED=true)
.env 里 MILVUS_REQUIRED=true
chunk_db_id 字段,schema 变更后可能需要 重新向量化。.env 中的 RAG_MIN_SCORE(默认 0.22)。REDIS_URL(或 REDIS_ADDR + REDIS_PASSWORD + REDIS_DB),用于 WebSocket 事件跨实例同步。REDIS_WS_CHANNEL 自定义事件频道(默认 ai_cs:ws_events)。把下面代码放到你网站的 </body> 前,核心是把 src 指向你自己的部署域名的 /chat。
说明:/chat 在 iframe 内会自动进入嵌入模式(也可显式加 ?embed=1),只显示聊天界面,不会出现第二个浮动按钮;宿主站点保留外层「打开/关闭」按钮即可,点一次即可对话。
<div id="ai-cs-widget" style="position: fixed; bottom: 20px; right: 20px; z-index: 9999;">
<button
id="ai-cs-toggle-btn"
style="width:56px;height:56px;border-radius:50%;background:#3b82f6;color:#fff;border:none;cursor:pointer;box-shadow:0 4px 12px rgba(0,0,0,.15);"
onclick="toggleChat()"
>
Chat
</button>
<iframe
id="ai-cs-chat-iframe"
src="https://你的域名/chat"
style="display:none;position:fixed;bottom:80px;right:20px;width:400px;height:600px;max-width:calc(100vw - 40px);max-height:calc(100vh - 100px);border:none;border-radius:12px;box-shadow:0 20px 25px -5px rgba(0,0,0,.1);"
></iframe>
</div>
<script>
function toggleChat() {
const iframe = document.getElementById("ai-cs-chat-iframe");
iframe.style.display = iframe.style.display !== "none" ? "none" : "block";
}
</script>
也可使用 frontend/public/widget.js(AICSWidget.init({ ... })),详见脚本内注释。
.env 的 MILVUS_REQUIRED 是否误开;不需要知识库时建议 MILVUS_DISABLED=trueRAG_MIN_SCORE(默认 0.22)X-User-Id 请求头X-Conversation-Token;客服接口须先登录并带 X-User-IdNEXT_PUBLIC_SITE_URL=https://你的域名,用于 canonical / OG / sitemap 生成curl http://<host>:<BACKEND_PORT>/health,再 docker logs ai-cs-backend --tail 50;Docker 部署时 DB_HOST 应为 mysql 而非 localhost<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=2930134478/AI-CS&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=2930134478/AI-CS&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=2930134478/AI-CS&type=Date" />
欢迎提交 Issue 和 Pull Request。报 Bug 请附上部署方式、后端日志与 .env 关键项(密码打码)。
MIT © 2025 2930134478