OpenClaw + 147API:把多模型调度从业务代码里“剥”出来

摘要:多模型接入真正难的不是“能不能调通”,而是接口差异、鉴权/Key 管理、流式、超时、重试、fallback 这些工程细节会迅速侵蚀业务代码。本文给一个可落地的做法:用 OpenClaw 做编排与运行时治理,用 147API 提供 OpenAI 风格 /v1 入口把调用口径收敛到一处。全篇只讲工程化:配置怎么写、怎么验证、踩坑怎么排。


1. 背景:多模型项目为什么越写越“脏”?

你一开始可能只是想“多接几个模型比一比效果”。但写着写着就变成了这样:

现状 代价
每家模型一套 SDK/参数/返回结构 迁移或 AB 实验变成全局重构
Key 分散在多个服务/环境变量里 轮换困难,出问题不好定位
错误码、超时、流式细节各不相同 业务层塞满 if-else 的兼容逻辑

最后你以为自己在写“智能体”,实际上写的是“接口适配层”。

要把工程拉回正轨,一个核心原则是:业务层只保留“一个调用口径”,模型选择与失败策略从业务代码移到网关/配置层。


2. 方案:OpenClaw 负责编排,147API 负责统一 /v1 入口

2.1 为什么这两个放在一起?

  • OpenClaw:更像一个可配置的 Agent 网关/运行时,把模型、fallback、工具等都放进配置里管理(文档入口:OpenClaw Docs)。
  • 147API:官网首页的页面描述(meta description)强调它用于 OpenAI 接口聚合管理,支持包括 Azure 在内的多种渠道,并提供单可执行文件与 Docker 镜像“一键部署”(来源:147ai.com)。从接口形态上看,它使用 OpenAI 风格的 /v1/... 路径;我对 https://147ai.com/v1/chat/completions 发起未授权请求会返回 401,并提示“未提供令牌”。

2.2 总体架构

业务/脚本/自动化任务
        ↓
OpenClaw(编排、模型选择、fallback、工具调用)
        ↓
147API(统一 /v1 入口 + 令牌鉴权)
        ↓
你在 147API 里实际可用的模型能力(文本/推理/多模态)

这套组合的目标不是“追求花里胡哨”,而是把工程问题拆清楚:

  1. 业务只关心 base_url + model
  2. fallback、allowlist、可观测性归到 OpenClaw/配置层。
  3. 具体模型 ID/参数,以 147API 控制台为准(别在文章里写死,避免误导)。

3. 实战:把 147API 配进 OpenClaw(自定义 Provider)

3.1 OpenClaw 配置入口确认

OpenClaw 网关读取的配置文件默认在:

  • ~/.openclaw/openclaw.json

配置是 JSON5(支持注释和尾逗号),并且可以用向导初始化(参考:Configuration):

openclaw onboard

提醒一句:OpenClaw 对配置做严格校验,未知字段会导致网关拒绝启动(同上面的 Configuration 文档)。

3.2 Provider 配置(OpenAI 风格 / openai-completions)

OpenClaw 的 Provider 配置支持自定义 baseUrlapiKey、以及 api 协议类型。官方文档里给了 api: "openai-completions" 的示例(参考:Model Providers)。

下面是一个最小可改的模板,把 provider 命名为 api147

// ~/.openclaw/openclaw.json(片段)
{
  models: {
    mode: "merge",
    providers: {
      api147: {
        baseUrl: "https://147ai.com/v1",
        apiKey: "${API147_KEY}",
        api: "openai-completions",
        // 模型 id 以 147API 控制台/文档为准,这里只放占位符
        models: [
          { id: "your-model-id", name: "Primary (from 147API)" },
          { id: "your-fallback-model-id", name: "Fallback (from 147API)" },
        ],
      },
    },
  },

  agents: {
    defaults: {
      model: {
        primary: "api147/your-model-id",
        fallbacks: ["api147/your-fallback-model-id"],
      },
      // 如果你设置了 models(allowlist),一定要把可用模型列进去
      models: {
        "api147/your-model-id": { alias: "主力" },
        "api147/your-fallback-model-id": { alias: "兜底" },
      },
    },
  },
}

Key 用环境变量注入(示例):

export API147_KEY="你的 147API 令牌"

4. 踩坑:为什么切模型没反应?(Model is not allowed)

OpenClaw 有一个容易踩的机制:如果你设置了 agents.defaults.models,它会变成 allowlist(允许列表)。当你在会话里用 /model 选择了不在 allowlist 里的模型,会直接报:

Model "provider/model" is not allowed. Use /model to list available models.

这条规则来自官方文档(参考:Models CLI)。排查顺序很简单:

  1. 你是否配置了 agents.defaults.models
  2. 你要用的 api147/<model-id> 是否在列表里?
  3. 不想限制就删掉 allowlist;想限制就补全列表。

5. 稳定性:fallback + 令牌轮换(别在业务里手搓)

在 OpenClaw 里,失败处理至少分两层:

  • 模型 fallback:按 agents.defaults.model.fallbacks 的顺序尝试下一个模型
  • Provider 内的鉴权档案轮换:同一个 provider 内,如果你配置了多个 auth profile,会有轮换/冷却机制(参考:Model Failover

你不一定第一天就把它用复杂,但建议第一天就把“失败路径”设计出来:哪类错误重试、哪类错误切 fallback、哪类错误直接报给业务层。


6. 不引入 OpenClaw,先做连通性验证(Python 最小示例)

如果你只是想验证 base_url 方式能否工作,可以先用 OpenAI Python SDK 做一段最小调用。注意:model 的具体 ID 需要你去 147API 控制台确认。

from openai import OpenAI

client = OpenAI(
    api_key="你的 147API 令牌",
    base_url="https://147ai.com/v1",
)

resp = client.chat.completions.create(
    model="your-model-id",
    messages=[
        {"role": "system", "content": "你是一个严谨的工程助手。"},
        {"role": "user", "content": "用一段话说明:为什么统一网关能降低多模型接入成本?"},
    ],
)

print(resp.choices[0].message.content)

几个排错点(很常见):

  1. base_url 通常以 /v1 结尾。
  2. 401 且提示“未提供令牌”,大概率是令牌没带上;带了但仍 401,可能是令牌无效。
  3. OpenAI SDK 默认用 Authorization: Bearer <api_key> 方式携带令牌。

你也可以用 curl 验证鉴权是否生效(不带令牌会 401):

curl -i -X POST 'https://147ai.com/v1/chat/completions' \
  -H 'Content-Type: application/json' \
  -d '{"model":"your-model-id","messages":[{"role":"user","content":"ping"}]}'

7. 多模态与异步:图片/视频别按“文本请求”写

多模态调用最容易踩的坑是把它当成“更大的文本请求”。实际上它更像任务系统:

  • 图片:注意输入形态(URL / Base64 / 文件)、存储与回传
  • 视频:更建议按异步任务设计(Task ID、状态查询、超时、取消、重试)

OpenClaw 也提供了 agents.defaults.imageModel 用来处理“主模型无法接收图片输入时的自动切换”(参考:Models CLI)。即便你现在不用多模态,也建议把这条机制记在脑子里:以后接入会少走弯路。


8. 总结

核心就一句话:把多模型接入从“业务代码”搬到“统一入口 + 配置治理”。

你最终想要的不是“能调通一个模型”,而是能长期跑的一条流水线:模型可换、失败可控、成本可算、问题可追。

如果你已经在用 OpenClaw 做 Skill,把 147API 接成 Provider 之后,下一步通常就是:把路由策略、fallback 策略、观测指标补齐。到那一步,才算真的进入“工程化”。

posted @ 2026-03-04 12:02  147API  阅读(0)  评论(0)    收藏  举报