Files
cloudpods/docs/aiproxy/functional-test-climc.md
Zexi Li 4237ce52ea feat(llm): sync llm deployment with aiproxy catalog and routing (#25013)
Add auto_register_aiproxy on llm_deployment creation, background sync task,
and register/unregister CLI actions. Link aiproxy providers, routings, and
models to llm replicas via llm_id and llm_deployment_id fields.
2026-06-22 19:35:50 +08:00

10 KiB
Raw Blame History

aiproxy 功能测试climc + 通义千问 DashScope

本文用 climc 配置 aiproxy 资源,并用 curl 调用 OpenAI 兼容接口 POST /v1/chat/completions 做端到端验证。

安全:请勿把 DashScope API Key 写进脚本、文档或提交到 Git。在 shell 里用环境变量 DASHSCOPE_API_KEY 传入。若 Key 曾在聊天/工单中泄露,请到阿里云控制台轮换。

前置条件

说明
服务 aiproxy 主节点已部署Keystone 中已注册 aiproxy 服务及 public endpoint
数据库 主节点已执行 InitDBcatalog 中已有 aliyun provider 及 qwen-* 模型(首次启动 master 会自动 seed
客户端 source /etc/yunion/rcadmin(或等价 rc 文件),climc 能正常 list
工具 jq(脚本与下文 curl 示例用于解析 JSON
网络 aiproxy 节点能访问 https://dashscope.aliyuncs.com

一键脚本(交互式,推荐)

从 catalog 选择 模型提供商model_key,终端输入 API Key或使用环境变量跳过输入自动完成非流式 + 流式 chat

source /etc/yunion/rcadmin
export CLIMC_OUTPUT_FORMAT=json
bash scripts/test/aiproxy/aiproxy-functional-test.sh

也可预置后减少交互(仍会选择模型、是否流式,除非全部用环境变量):

export DASHSCOPE_API_KEY='你的 DashScope API Key'   # 或 AIPROXY_FT_API_KEY
export AIPROXY_FT_PROVIDER=aliyun
export AIPROXY_FT_MODEL=qwen-turbo
bash scripts/test/aiproxy/aiproxy-functional-test.sh

通义快捷入口:bash scripts/test/aiproxy/aiproxy-functional-test-qwen.sh(默认 aliyun)。
小米 MiMo 见 functional-test-climc-mimo.mdaiproxy-functional-test-mimo.sh)。

非交互CI

export AIPROXY_FT_NONINTERACTIVE=1
export AIPROXY_FT_PROVIDER=aliyun
export AIPROXY_FT_MODEL=qwen-turbo
export AIPROXY_FT_API_KEY='...'
export AIPROXY_FT_SKIP_STREAM=1   # 可选,跳过流式
bash scripts/test/aiproxy/aiproxy-functional-test.sh
环境变量 说明
AIPROXY_FT_PROVIDER provider_key(如 aliyunxiaomi
AIPROXY_FT_MODEL model_key(如 qwen-turbo
AIPROXY_FT_API_KEY 上游 API Key通用
DASHSCOPE_API_KEY / MIMO_API_KEY 按提供商兼容的旧变量名
AIPROXY_FT_SKIP_STREAM 1 跳过流式;0 强制流式
AIPROXY_URL 留空则从 endpoint-list 解析

测试流程概览

flowchart LR
  VK[ai_virtual_key] --> RT[ai_routing]
  RT --> RM[ai_routing_model]
  RM --> P[ai_provider aliyun]
  RM --> M[ai_model qwen-turbo]
  P --> K[ai_key secret]
  K --> DS[DashScope API]

0a. ai_provider 创建测试脚本

自定义 provider非 catalog seed创建与校验

source /etc/yunion/rcadmin
bash scripts/test/aiproxy/aiproxy-ai-provider-create-test.sh

交互输入:资源名、provider_keybase_url、是否 --enabled。非交互示例:

export AIPROXY_PROVIDER_FT_NONINTERACTIVE=1
export AIPROXY_PROVIDER_FT_NAME=my-vllm
export AIPROXY_PROVIDER_FT_PROVIDER_KEY=my-vllm
export AIPROXY_PROVIDER_FT_BASE_URL=http://127.0.0.1:8000/v1
bash scripts/test/aiproxy/aiproxy-ai-provider-create-test.sh

provider_key 须全局唯一;与 InitDB catalogaliyun)重复会失败。完整 config 可用 AIPROXY_PROVIDER_FT_CONFIG='{"base_url":"..."}'

0. ai_proxy_node多副本 / 路由绑定)

列出 aiproxy 实例节点InitDB 后默认有 primary

climc ai-proxy-node-list
climc ai-proxy-node-show primary

注册 standby 节点(与进程内 register 心跳相同,一般由 standby 自动调用;手工测试可用):

climc ai-proxy-node-register --address https://standby-host:30938 --hb-timeout 120

手工创建/更新节点(需具备写权限策略):

climc ai-proxy-node-create standby-1 \
  --address https://standby-host:30938 \
  --access-address https://aiproxy-standby.example.com:443 \
  --hb-timeout 120 \
  --enabled

climc ai-proxy-node-update primary --address https://primary-host:30938 --access-address https://aiproxy.example.com:443
climc ai-proxy-node-enable primary
climc ai-proxy-node-disable <node-id>

ai_routing 绑定到指定节点chat 须走该节点 public endpoint

climc ai-routing-update aiproxy-ft-routing --ai-proxy-node-id primary

创建 ai_routing 时若省略 --ai-proxy-node-id,默认绑定 primary 节点;更新时显式传空值仍可清空绑定(任意 aiproxy 节点均可匹配)。

1. 检查 Keystone endpoint

climc endpoint-list --service aiproxy --interface public

应能看到当前 region 的 public URL脚本会取第一条用于 curl

2. 检查 catalogInitDB seed

climc ai-provider-list --provider-key aliyun
climc ai-provider-show aliyun
climc ai-model-list --ai-provider-id aliyun --model-key qwen-turbo

确认 provider_key=aliyunconfig.base_urlhttps://dashscope.aliyuncs.com/compatible-mode,且存在模型 model_key=qwen-turbocatalog 固定 id / namealiyun-qwen-turbo)。

3. 注册上游 API Keyai_key

将 DashScope Key 存为 ai_key,供 chat 时按 provider 加权选取:

climc ai-key-create qwen-dashscope-ft \
  --ai-provider-id aliyun \
  --secret "${DASHSCOPE_API_KEY}" \
  --weight 10 \
  --enabled

校验:

climc ai-key-list --ai-provider-id aliyun
climc ai-key-show qwen-dashscope-ft

确认 ai_provider_idaliyun,且 enabled=trueai_key 默认 disabled创建时需 --enabled;若已存在但被禁用,执行 climc ai-key-enable qwen-dashscope-ft)。若曾用错误参数创建过同名 key可更新

climc ai-key-update qwen-dashscope-ft \
  --ai-provider-id aliyun \
  --secret "${DASHSCOPE_API_KEY}" \
  --weight 10
climc ai-key-enable qwen-dashscope-ft

secret 在 API 中通常不回显,仅用于上游调用。)

4. 创建 Virtual Key客户端鉴权

climc ai-virtual-key-create aiproxy-ft-vk

记下返回的 virtual_key(形如 sk-...)。查看:

climc ai-virtual-key-list
climc ai-virtual-key-show aiproxy-ft-vk

Virtual key 归属当前 climc 用户的 项目;后续 ai_routing 须在同一项目(或共享到该项目)下。

5. 创建项目路由ai_routing + models

将项目内请求 model=qwen-turbo 指到 catalog 的 aliyun/qwen-turbo。

精确匹配--model-key qwen-turbo 与请求 body 中 model 完全一致时命中(优先于 --model-pattern 通配规则)。

modelsai_model_id 使用 catalog 固定 id与 name 相同,如 aliyun-qwen-turbo),或在指定 ai_provider_id 时也可填 model_key(如 qwen-turbo

climc ai-routing-create aiproxy-ft-routing \
  --priority 10 \
  --model-key qwen-turbo \
  --models '[{"ai_provider_id":"aliyun","ai_model_id":"qwen-turbo","priority":1}]'

或手工指定 name

climc ai-routing-create aiproxy-ft-routing \
  --priority 10 \
  --models '[{"ai_provider_id":"aliyun","ai_model_id":"aliyun-qwen-turbo","priority":1}]'

查看绑定模型:

climc ai-routing-show aiproxy-ft-routing

也可事后调整:

climc ai-routing-set-models aiproxy-ft-routing \
  --models '[{"ai_provider_id":"aliyun","ai_model_id":"qwen-plus","priority":1}]'

可选:将规则绑定到指定 aiproxy 实例(多副本时):

# 仅当需要固定到 primary 等节点时
climc ai-routing-update aiproxy-ft-routing --ai-proxy-node-id primary

6. Chat completionscurl

climc 暂无 chat 子命令,用 public endpoint + virtual key 调用(-k 跳过 TLS 证书校验,适用于自签或内网 HTTPS

AIPROXY_URL="${AIPROXY_URL:-$(climc endpoint-list --service aiproxy --interface public --limit 1 \
  --output-format json | jq -r '.data[0].url // empty')}"

VK="$(climc ai-virtual-key-show aiproxy-ft-vk --output-format json \
  | jq -r '.virtual_key')"

curl -k -sS "${AIPROXY_URL%/}/v1/chat/completions" \
  -H "Authorization: Bearer ${VK}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-turbo",
    "messages": [{"role": "user", "content": "用一句话介绍通义千问"}],
    "max_tokens": 128
  }' | jq .

期望HTTP 200JSON 含 choices[0].message.contentusage

6b. 流式 Chatcurl / 脚本 step 7

一键脚本在步骤 6 非流式成功后,默认继续执行流式校验(聚合 choices[0].delta.content)。跳过流式:

export AIPROXY_FT_SKIP_STREAM=1

手动 curlSSEdata: [DONE] 结束):

curl -k -sS -N -o /tmp/aiproxy-ft-stream.sse \
  "${AIPROXY_URL%/}/v1/chat/completions" \
  -H "Authorization: Bearer ${VK}" \
  -H "Content-Type: application/json" \
  -d '{"model":"qwen-turbo","stream":true,"messages":[{"role":"user","content":"hi"}],"max_tokens":64}'

期望HTTP 200响应体含 data: {...} 行且至少一条 delta.content 非空;最后为 data: [DONE]

7. 负向用例(可选)

场景 操作 期望
错误 virtual key Authorization: Bearer sk-invalid 4xxvirtual key 无效
无路由 climc ai-routing-disable aiproxy-ft-routing 或删除后再 chat 404无匹配 routing
禁用 virtual key climc ai-virtual-key-disable aiproxy-ft-vk 4xx
provider 限制 create vk 时 --limits '{"allowed_ai_provider_ids":["openai"]}' 4xxprovider 不允许

8. 清理(可选)

climc ai-routing-delete aiproxy-ft-routing
climc ai-virtual-key-delete aiproxy-ft-vk
climc ai-key-delete qwen-dashscope-ft

常见问题

no ai_routing matched for virtual key project
Virtual key 的 project_id 与 routing 所在项目不一致,或 routing 未 enabled、未共享到该项目。用同一 climc 项目上下文创建两者。

no api_key for ai_provider
未创建 ai_key,且 ai_provider.config 里也没有 api_key。按步骤 3 创建 ai_key

DashScope 401/403
检查 DASHSCOPE_API_KEY 是否有效、是否开通对应模型。

多副本 ai_routing 绑定其它节点
若 routing 指定了 ai_proxy_node_id,须访问该节点的 public endpoint或去掉绑定。