7.0 KiB
7.0 KiB
数字人对接中转服务
基于 Docker Compose 部署的数字人对接中转服务,连接客户端与 Dify LLM 平台,支持流式与非流式对话、多轮会话上下文(Redis 缓存)。
目录
架构
Client --> Nginx/Traefik(反向代理) --> digital-human(:8000) --> Dify LLM Platform
| |
| +--> Redis(:6379, 容器内网)
- digital-human:FastAPI 中转服务,转发请求至 Dify 并统一响应格式
- Redis:存储 session_id 与 dify conversation_id 的映射关系,支持多轮对话
- 两者通过 Docker Compose 内部 DNS (
redis) 通信,不占用宿主机端口
快速部署
1. 克隆项目
git clone https://github.com/ClawCopilot/digital-human-dify-relay.git
cd digital-human-dify-relay
2. 配置环境变量
cp .env.example .env
# 编辑 .env,填入以下两个必填变量
.env 必填项:
# Dify 服务地址(末尾不要加 /chat-messages,代码会自动拼接)
DIFY_URL=https://your-dify-domain.com/v1
# Dify API 密钥(纯密钥,不要加 Bearer 前缀)
DIFY_API_KEY=app-PDkSHiHZsZIluoZF7N2OlNZM
3. 启动服务
docker compose up -d
4. 验证服务
# 健康检查
curl http://localhost:8000/
# 重启后确认容器状态(healthy 表示正常)
docker ps | grep digital-human
接口说明
POST /digital-human
数字人中转核心接口。
请求体:
{
"messages": [
{ "content": "你好,请用一句话介绍自己。" }
],
"app_id": "app-xxxxxxxx",
"user": "user-001",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"is_stream": true
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
messages |
Array |
✅ | 消息列表,目前只取第一条 content 作为 Dify query |
app_id |
string |
✅ | Dify 应用 ID |
user |
string |
✅ | 用户标识,用于 Dify 会话上下文 |
session_id |
string |
✅ | 会话 ID,用于关联多轮对话上下文,留空自动生成 |
is_stream |
boolean |
✅ | true = SSE 流式响应,false = 非流式阻塞返回 |
响应(非流式 is_stream=false):
{
"id": "131424542124",
"created": 20230512084843,
"choices": [
{
"index": 0,
"message": {
"content": "你好!我是..."
}
}
]
}
响应(流式 is_stream=true):
SSE 格式,每个 chunk:
data: {"id":"1231414141541252525","created":20230512084843,"choices":[{"message":{"content":"你"}}]}
data: {"id":"1231414141541252525","created":20230512084843,"choices":[{"message":{"content":"好"}}]}
...
data: [DONE]
GET /
健康检查端点,用于 Docker healthcheck 和外部监控。
{ "status": "ok" }
环境变量
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
DIFY_URL |
✅ | — | Dify 服务地址,如 https://atwdify.antiwearvalve.com/v1 |
DIFY_API_KEY |
✅ | — | Dify API 密钥(纯密钥,不要加 Bearer 前缀) |
REDIS_HOST |
否 | redis |
Redis 主机,Docker Compose 内部 DNS,始终填 redis |
REDIS_PORT |
否 | 6379 |
Redis 端口 |
DH_PORT |
否 | 8000 |
宿主机映射端口 |
注意:
DIFY_URL末尾不要包含/chat-messages,代码会自动拼接。
端口说明
| 端口 | 服务 | 说明 |
|---|---|---|
${DH_PORT:-8000} |
digital-human | 中转服务,通过反向代理或直连访问 |
| — | Redis | 默认不暴露,仅在 Docker 容器网络内部互通 |
如需从宿主机直连 Redis,合并 docker-compose.redis-expose.yml:
docker compose -f docker-compose.yml -f docker-compose.redis-expose.yml up -d
本地测试
项目内置两个测试页面:
| 文件 | 用途 | 访问方式 |
|---|---|---|
test.html |
测试中转服务 /digital-human 接口 |
浏览器直接打开或部署后访问 |
test-dify.html |
直连 Dify API,跳过中转 | 浏览器直接打开 |
test.html 使用方法
- 打开
test.html - 填写中转服务地址,如
https://chat-agent-demo.aigc-quickapp.com - 填写 Session ID(留空自动生成)
- 填写 App ID(对应 Dify 应用)
- 填写 User
- 填写测试消息
- 点击发送请求
常见问题
Q:容器状态为 unhealthy?
执行以下命令查看具体报错:
docker compose logs digital-human
常见原因:
.env中DIFY_URL或DIFY_API_KEY未填写或格式错误- Redis 连接失败(确保
REDIS_HOST=redis且两个容器在同一网络)
Q:POST /digital-human 返回 500?
通常是 Dify 请求失败。检查:
.env中DIFY_URL是否正确(末尾是否为/v1)DIFY_API_KEY是否有效- 服务器能否访问 Dify 地址:
curl -I $DIFY_URL
Q:Redis Connection refused?
确认 docker-compose.yml 中 REDIS_HOST: "redis" 生效,且 Redis 容器正常运行:
docker ps | grep redis
docker compose logs redis
Q:外网无法访问服务?
- 检查容器是否正常:
docker ps状态应为healthy - 检查防火墙:
sudo ufw allow 8000/tcp(或对应端口) - 通过域名访问时检查反向代理配置是否正确转发到容器端口
生产部署
- 反向代理:在 digital-human 前配置 Nginx/Caddy 进行 TLS termination
- HTTPS:生产环境务必使用 HTTPS
- 环境变量:
.env不要提交到代码仓库,已在.gitignore中排除 - Redis 高可用:可替换为外部 Redis 集群,修改
REDIS_HOST - 域名配置:将域名 DNS 解析到服务器,通过反向代理转发到容器端口
目录结构
.
├── docker-compose.yml # 主容器编排(Redis 默认内部模式)
├── docker-compose.redis-expose.yml # Redis 端口暴露扩展(按需合并)
├── Dockerfile # 应用镜像构建
├── digital-human.py # FastAPI 中转服务源码
├── requirements.txt # Python 依赖
├── .env.example # 环境变量模板
├── test.html # 中转服务测试页面
├── test-dify.html # Dify 直连测试页面
├── downloads/ # 独立部署包(Systemd + Shell)
└── README.md # 本文件