外观
阿里云百炼接入与验证
更新日期:2026-11-05。
本项目用百炼智能体应用 + 文档搜索类知识库承接原 Coze 聊天、会话上下文和知识库上传/删除功能。仅支持阿里云百炼,AI_PROVIDER 默认并且只能为 aliyun。知识库使用新版 RAG REST API,与聊天共用 DASHSCOPE_API_KEY,不再需要 RAM AccessKey ID/Secret。
代码与本地模拟测试已完成,当前环境的新版 RAG 知识库列表也已通过真实账号的只读查询。上传、索引、删除、知识检索效果和语音联调仍需按本文验收;未创建云资源或迁移旧文档。
1. 接入范围
| 功能 | 实现与行为 |
|---|---|
| 文本聊天 | 调用已发布的百炼智能体应用,支持增量 SSE |
| 多轮会话 | 将前端 conversation_id 映射为百炼 session_id |
| 默认/养老机器人 | 分别配置默认 APP ID 和可选养老 APP ID |
| 文字与语音 | 百炼生成文字,继续由现有火山引擎 TTS 合成语音 |
| 知识库上传 | 保留 TOS 原文件备份,再上传百炼、等待解析、追加知识库索引 |
| 状态查询 | Celery 后台推进;前端弹窗每 5 秒刷新,也可手动调用同步接口 |
| 知识库删除 | 按记录保存的供应商、业务空间和知识库删除,再删除本地记录 |
| 清除上下文 | 客户端丢弃会话 ID,下次创建新会话;不会删除百炼云端历史 |
| 取消回答 | 本次采用的应用 API 未实现按 chat_id 云端取消;接口返回失败说明,前端仍断开 SSE 并停止播放。不能据此认定云端生成已取消或停止计费 |
本次接入的是 POST /api/v1/apps/{app_id}/completion,不是 OpenAI 兼容模型接口,也不是百炼的另一套 Session/Agent 运行时 API。应用 API 的 session_id 有有效期,过期后需清除本地会话重新发起。应用 API 参考
2. 在阿里云控制台准备资源
本次默认按**中国站、华北 2(北京)**接入。应用、知识库、API Key 和接入地址要属于相匹配的站点与地域。国际站接入时要成组替换并另行验证,不能只修改域名。
- 开通阿里云百炼,进入目标业务空间,记录 Workspace ID。
- 创建文档搜索类知识库,完成初始化,记录 知识库 ID。本代码向已有知识库追加文档,不会自动创建知识库。
- 创建智能体应用,选择可用模型,迁移原 Coze 的提示词、角色设定和业务约束。
- 在应用中关联上一步的知识库,配置检索策略并发布应用,记录 APP ID。仅把文档上传到百炼应用数据中,不会自动让应用检索它。
- 幼教和养老分别发布应用并记录 APP ID,各自关联对应知识库。文件上传和列表通过
bot选择目标知识库,删除及后台同步按文件记录保存的知识库处理。 - 创建目标业务空间可用的 DashScope API Key,同时用于应用和 RAG API 调用。
- 如果 API Key 归属于 RAM 用户,该用户仍需具备百炼数据操作权限并加入目标业务空间。官方认证文档要求
AliyunBailianDataFullAccess;本项目不再要求创建或配置 RAM AccessKey。
| 知识库操作 | 新版 REST 接口 |
|---|---|
| 申请上传租约 | POST /api/v1/connector/dash/applyFileUploadLease |
| 注册文件 | POST /api/v1/connector/dash/addFile |
| 查询解析状态 | POST /api/v1/connector/dash/describeFile |
| 向指定知识库追加文件 | POST /api/v1/indices/rag/index/job/create |
| 查询导入任务与文件状态 | GET /api/v1/indices/rag/index_job/status |
| 从知识库删除文档 | POST /api/v1/indices/rag/index/delete_file |
| 从数据中心删除文件 | POST /api/v1/connector/dash/deleteFile |
新版接口用 Authorization: Bearer <API-Key> 鉴权,Base URL 为 https://{workspace_id}.cn-beijing.maas.aliyuncs.com。API Key 的归属账号仍需具有目标数据的操作权限。新版认证说明、API 概览
注意区分知识库 ID和检索服务 Agent ID:知识库列表接口返回 data.rows[].id,作为 ALIYUN_BAILIAN_KNOWLEDGE_ID;阿里云请求字段 indexId / index_id 指的也是这个知识库 ID,项目配置使用业务含义明确的名称;检索服务的 Agent ID 不能代替它。可在百炼控制台知识库列表核对,也可用下方只读命令检查当前配置。
3. 配置后端
本地开发使用 packages/server/.env,参考同目录 .env.example 补充配置,不要覆盖已有 MySQL、Redis、TOS 和 TTS 配置。线上 Docker 部署统一使用 deploy/.env,由 Compose 注入 server 和 worker;不需要再配置镜像内的 .env。线上步骤见 Docker 部署。所有阿里云凭证仅保存在后端。
dotenv
AI_PROVIDER=aliyun
# 智能体应用
DASHSCOPE_API_KEY=你的百炼API_Key
ALIYUN_BAILIAN_APP_ID=已发布的默认应用ID
ALIYUN_BAILIAN_YANGLAO_APP_ID=
ALIYUN_DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/api/v1
# 同一业务空间下的文档搜索类知识库
ALIYUN_BAILIAN_WORKSPACE_ID=业务空间ID
ALIYUN_BAILIAN_KNOWLEDGE_ID=幼教知识库ID
ALIYUN_BAILIAN_YANGLAO_KNOWLEDGE_ID=养老知识库ID
ALIYUN_BAILIAN_CATEGORY_ID=default
# 可选:留空时由 Workspace ID 自动生成;不能填旧 SDK 域名
ALIYUN_RAG_BASE_URL=| 变量 | 是否必填 | 说明 |
|---|---|---|
AI_PROVIDER | 否 | 仅支持 aliyun,默认 aliyun;其他值报错 |
DASHSCOPE_API_KEY | 必填 | 聊天与 RAG 管理共用的 API Key |
ALIYUN_BAILIAN_APP_ID | 聊天必填 | 已发布的应用 ID,不是模型名称 |
ALIYUN_BAILIAN_YANGLAO_APP_ID | 否 | bot=yanglao 时使用;留空复用默认应用 |
ALIYUN_DASHSCOPE_BASE_URL | 有默认值 | 应用 HTTP API 基址,包含 /api/v1 |
ALIYUN_BAILIAN_WORKSPACE_ID | 知识库必填 | 应用位于子业务空间时也会作为请求头传入 |
ALIYUN_BAILIAN_KNOWLEDGE_ID | 幼教知识库必填 | 默认/bot=youlemei 使用的文档搜索类知识库 |
ALIYUN_BAILIAN_YANGLAO_KNOWLEDGE_ID | 养老知识库必填 | bot=yanglao 使用;缺少时明确报错,不会使用幼教知识库 |
ALIYUN_BAILIAN_CATEGORY_ID | 否 | 应用数据类目 ID,默认 default |
ALIYUN_RAG_BASE_URL | 否 | 留空时使用 https://{Workspace ID}.cn-beijing.maas.aliyuncs.com,不附加 /api/v1 |
语音双流仍需要 VOL_APPID、VOL_ACCESS_TOKEN、VOL_VOICE_TYPE;文件原件仍需要 VOL_DUOLI_ACCESS_KEY、VOL_DUOLI_ACCESS_SECRET、VOL_TOS_REGION、VOL_TOS_BUCKET_NAME。ARK_* 继续供现有 PDF/OCR 相关功能使用。本次没有把这些能力迁往阿里云。
语音 WebSocket 显式直连 openspeech.bytedance.com,避免继承系统代理或 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 导致 did not receive a valid HTTP response from proxy。此设置只作用于语音 WebSocket,服务运行环境需能直接访问该域名的 443 端口。
聊天文字与语音同步
双流接口 chat/text_bidirectional 按语音服务的自然分句配对文字与音频。chunk 事件中的文字用于缓存;chunk_voice 中的 audio_base64 是可独立播放的完整 WAV 音频,full_content 是读到这一句时对应的累计文字。前端收到音频元素的 playing 事件后才显示该段文字,避免模型生成速度快于朗读速度时文字提前显示。
end 表示服务端生成结束,前端仍需依次播完剩余音频;全部播放结束后才展示最终完整答案。打断、新问题、清除对话和退出页面会停止播放并丢弃旧请求。浏览器禁止自动播放或音频播放失败时,本轮切换为文字显示并提示用户。
此版本需要同时更新 server 和 site。验收时检查长回答分句播放、慢速网络、新问题打断旧回答,以及浏览器禁止自动播放的情况。前端回归测试运行 pnpm --filter site test,后端运行 .venv/bin/python -m pytest packages/server/tests -q。分句事件定义见火山引擎双向流式协议。
4. 安装、数据库迁移与启动
从仓库根目录执行:
bash
# 首次使用才创建虚拟环境:uv venv .venv --python 3.12
source .venv/bin/activate
uv sync --project packages/server --active
pnpm install
# 在已有数据库上执行前先备份;此命令增加供应商与索引状态字段
.venv/bin/python packages/server/manage.py migrate
.venv/bin/python packages/server/manage.py check
# 前端默认 4904,后端默认 4900
pnpm dev另一个终端启动后台同步:
bash
pnpm workerMySQL 和 Redis 需已运行。若 4900 已被占用,可用 PORT=4901 pnpm dev;这时前端仍监听 4904。
前端 packages/site/.env 中设置:
dotenv
VUE_APP_BASE_URL=/api/若本地后端换成 4901,则设置 API_PROXY_TARGET=http://127.0.0.1:4901;独立部署也可将 VUE_APP_BASE_URL 设为完整的后端 API 地址。修改前端环境变量后重启开发服务。不要把 API Key 放入任何 VUE_APP_* 变量。
5. 验证聊天
先用只读命令检查 RAG 配置:
bash
.venv/bin/python packages/server/manage.py check_aliyun_knowledge --bot youlemei
.venv/bin/python packages/server/manage.py check_aliyun_knowledge --bot yanglao该命令只查询知识库列表,验证 API Key/Workspace 是否可访问、当前 知识库 ID 是否存在;不会创建、上传或删除文件,也不会输出 API Key。
以下命令假设后端为 4900;按实际端口修改。
bash
curl -N --fail-with-body http://127.0.0.1:4900/api/chat/text \
--data-urlencode 'question=你好,请介绍你能提供的帮助'预期:收到 connecting、processing、created、多条 chunk,最后收到 completed。chunk.data 中包含 content、full_content、conversation_id、chat_id。出现 type=error 表示失败,即使 HTTP 状态码是 200。
保存返回的 conversation_id,连续问两轮:
bash
curl -N http://127.0.0.1:4900/api/chat/text \
--data-urlencode 'question=请记住,验证代号是松果七号' \
--data-urlencode 'conversation_id=上一轮返回的ID'
curl -N http://127.0.0.1:4900/api/chat/text \
--data-urlencode 'question=刚才的验证代号是什么' \
--data-urlencode 'conversation_id=上一轮返回的ID'再用 bot=yanglao 验证养老应用路由。清除会话调用:
bash
curl http://127.0.0.1:4900/api/chat/clear_conversation \
--data-urlencode 'conversation_id=当前ID'预期返回 status=0 和丢弃旧 ID 的说明。下一次请求不传旧 ID,应建立新会话。前端使用独立的百炼会话缓存,并按幼教/养老场景隔离,不会读取旧供应商的会话 ID。
语音验证:将上面的路径改为 /api/chat/text_bidirectional。预期同时收到文本 chunk 与音频 chunk_voice,最终 end;还需在前端 http://localhost:4904 验证声音实际可播放。文本接口成功而双流失败时,先核对火山 TTS 凭证、音色和 WebSocket 网络。
6. 验证知识库完整流程
前端按登录账号配置中的 bot 选择知识库:幼乐美和院校幼教账号传 youlemei,养老账号传 yanglao。文件上传请求携带同名表单字段,列表请求携带同名查询参数。不传时走幼教/默认知识库。
| 场景 | 聊天应用配置 | 文件知识库配置 |
|---|---|---|
幼教 youlemei | ALIYUN_BAILIAN_APP_ID | ALIYUN_BAILIAN_KNOWLEDGE_ID |
养老 yanglao | ALIYUN_BAILIAN_YANGLAO_APP_ID | ALIYUN_BAILIAN_YANGLAO_KNOWLEDGE_ID |
这两项配置分别控制应用调用和文件管理;还需在百炼控制台将每个已发布应用关联到对应知识库。后端不会仅凭这两个 ID 自动修改云端应用配置。
准备一个 PDF/DOC/DOCX 文件,写入可唯一识别的测试事实,例如“百炼迁移验收暗号为蓝鲸四十二号”。仍沿用单文件不超过 20MB 的限制。
bash
curl http://127.0.0.1:4900/api/file/create \
-F 'bot=youlemei' \
-F 'title=百炼迁移验收' \
-F 'file=@/你的绝对路径/验收.pdf'预期 status=0,数据包含 provider=aliyun、remote_document_id 和 sync_status=parsing。此时不代表已经可以检索。记下本地数字 id。
bash
curl 'http://127.0.0.1:4900/api/file/list?page=1&size=100&bot=youlemei'
# 手动检查并推进一个步骤;未启动 worker 时也可恢复
curl -X POST http://127.0.0.1:4900/api/file/sync/本地文件ID养老场景将上传表单和列表查询中的 bot 改为 yanglao。列表仅返回所选业务空间及知识库的本地文件记录,控制台中已有文件不会自动导入本地列表。
每次手动检查至少间隔 5 秒。正常状态流转为:
text
parsing(应用数据文件解析)
→ indexing(知识库索引作业)
→ synced(作业完成且该文件 FINISH,可验证检索)解析或索引失败会返回 failed 和 sync_error。RAG 状态查询请求短暂失败不会被误标为同步成功;worker 会重试,前端弹窗也会检查状态。如果提交索引的结果无法确认(如请求超时),状态变为 attention,停止自动重复提交,并禁止删除。先在控制台核对该文件、Workspace 和 Index 对应的导入任务 ID(ingestionId,不是旧 SDK 的 Data.Id),再运行:
bash
.venv/bin/python packages/server/manage.py sync_aliyun_knowledge --file-id 本地文件ID --job-id 已核对的ingestionId随后重新打开前端弹窗或调用 file/sync 继续推进。仅检查状态时可以省略 --job-id。若控制台确认根本没有作业,需先人工核对、修复该条记录,再重新处理,避免盲目重传。
worker 最多重试 720 次,停止重试后可通过手动接口继续检查。索引高峰期可能持续较长时间,不要重复上传同一个文件。
上传后的文件先达到 PARSE_SUCCESS 才追加到知识库;新版解析失败状态 FAIL 也会被识别。文件详情说明
提交时显式指定 sourceType=DATA_CENTER_FILE 和 docIds,只导入此次上传的文件,避免默认导入数据中心的全部文件。返回 ingestionId 存入本地 index_job_id 字段。导入任务说明
查询用 GET query string 传入 index_id 和 job_id,检查 data.ingestion_status 以及 data.rows 中对应文件的 FINISH 状态,避免仅凭作业完成就标记文件成功。任务状态说明
当状态为 synced 后,开启新会话询问文档中的验收暗号,检查答案和百炼控制台检索调试结果。若应用未关联同一个 Index,上传和索引成功也不会检索到该文件。
删除此次创建的测试文件:
bash
curl -X DELETE http://127.0.0.1:4900/api/file/delete/本地文件ID预期从百炼知识库、百炼应用数据和本地列表移除。再开启新会话验证测试事实无法从该知识库召回;已存在的会话历史仍可能包含旧答案。远端删除失败时保留本地记录,便于重试;解析/索引中禁止删除,以避免后台任务再次写入索引。TOS 原件沿用既有备份保留策略,删除知识库记录不会删除该备份。
删除时先调用知识库的 index/delete_file(参数为 index_id、doc_ids)移除文档和切片,再调用数据中心 deleteFile(参数为 fileId)删除原文件。新版 deleteFile 也会使引用该文件的索引失效。删除文档、删除文件
7. 历史数据处理
- 已移除 Coze 客户端、配置和前端直连接口,不支持切换回旧供应商。
- 历史数据库迁移和
coze_document_id字段保留,避免丢失已有文件标识;旧记录不会改标为百炼记录,也不会自动复制远端内容。 file/list仅列出百炼当前业务空间、当前bot对应知识库的记录。旧文件需要从原始文件重新上传到百炼。- 运行数据库迁移将新建文件的默认供应商改为
aliyun,不修改既有记录的归属。 - 前端仅配置后端
VUE_APP_BASE_URL;本地默认/api/代理到http://127.0.0.1:4900,百炼 API Key 和应用 ID 均留在服务端。
8. 常见问题
| 现象 | 检查与处理 |
|---|---|
| 缺少 APP ID/API Key | 检查 packages/server/.env,重启后端;不会自动回退 Coze |
| HTTP 401/403 或应用不可调用 | 检查 API Key、应用是否发布、地域/业务空间是否一致 |
| 知识库上传被拒绝 | 检查 API Key 的数据权限、归属用户是否加入业务空间、Workspace/Index/类目是否有效 |
parsing 长时间未改变 | 检查百炼应用数据解析状态、Redis 与 pnpm worker;调用同步接口 |
indexing 长时间未改变 | 检查 index_job_id 对应作业及单文件状态;不要将“API 请求成功”当成“索引成功” |
attention | 按上文核对云端作业并绑定 Job ID,不要直接删除或重复上传 |
failed | 查看 sync_error 和百炼控制台;修正原文件后删除失败记录再重新上传 |
| 有索引但回答不知道 | 检查发布应用关联的知识库、检索阈值,使用新会话验证 |
| 切换供应商后会话报错 | 清除前端保存的旧会话 ID,再开始新会话 |
| 旧版配置仍在 | 移除对 ALIYUN_BAILIAN_ENDPOINT 和 ALIBABA_CLOUD_* 的依赖,重启后端/worker;本项目已不读取这些字段 |
| DB 写入失败后远端残留 | 查看日志中的 workspace/file ID;待解析完成后在百炼控制台清理,不能只删除本地行 |
| 前端仍调用旧环境 | 修改 VUE_APP_BASE_URL 并重启/重新构建前端;确认访问的是 4904 上的新页面 |
9. 本地回归与验收记录
无需真实云凭证的自动测试:
bash
.venv/bin/python -m pytest packages/server/tests -q
pnpm build测试以模拟的应用 SSE、新版 HTTP JSON 响应和 SQLite 数据库验证请求参数、异常与提前断流、状态持久化、上传回滚和删除顺序。真实的模型回答、权限策略、知识召回效果和音频播放仍需实际账号验收。
验收时记录:日期、地域、Workspace/APP/知识库 ID、测试文件本地 ID/远端 ID/作业 ID、请求 ID、单轮与多轮结果、知识检索结果、删除后检索结果和音频结果。不要记录完整密钥或预签名上传 URL。