2026-04-22 16:49:18 +08:00
2026-04-22 16:49:18 +08:00

数字人对接中转服务

基于 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 使用方法

  1. 打开 test.html
  2. 填写中转服务地址,如 https://chat-agent-demo.aigc-quickapp.com
  3. 填写 Session ID(留空自动生成)
  4. 填写 App ID(对应 Dify 应用)
  5. 填写 User
  6. 填写测试消息
  7. 点击发送请求

常见问题

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:外网无法访问服务?

  1. 检查容器是否正常:docker ps 状态应为 healthy
  2. 检查防火墙:sudo ufw allow 8000/tcp(或对应端口)
  3. 通过域名访问时检查反向代理配置是否正确转发到容器端口

生产部署

  1. 反向代理:在 digital-human 前配置 Nginx/Caddy 进行 TLS termination
  2. HTTPS:生产环境务必使用 HTTPS
  3. 环境变量:.env 不要提交到代码仓库,已在 .gitignore 中排除
  4. Redis 高可用:可替换为外部 Redis 集群,修改 REDIS_HOST
  5. 域名配置:将域名 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                         # 本文件
Description
No description provided
Readme 13 MiB
Languages
HTML 60.6%
Python 32.2%
Dockerfile 4.5%
Shell 2.7%