model id 以 147AI 实际提供的列表为准

OpenClaw + 147AI 实战:用 OpenAI 风格(/v1)统一网关,搭一条多模型智能体流水线

关键词:OpenClaw,147AI,OpenAI 风格,/v1,API 网关,多模型调度,故障切换,智能体流水线

摘要:大模型更新越来越快,真正拖慢交付的往往不是 Prompt,而是接口差异、Key 管理、限流、流式和兜底这些工程细节。本文用 OpenClaw 负责流程编排与任务执行,用 147AI 的 OpenAI 风格 /v1 入口统一调用口径,给出一段可参考的 Provider 配置和一份 Python 最小示例,帮助你把“采集 → 清洗 → 调度 → 输出”做成一条能长期维护的流水线。

如果你要跑的不是一次性 Demo,而是要稳定地跑一段时间(采集、归档、生成内容、分发),先把“入口统一 + 模型可替换”这两件事做掉,后面会少很多返工。


引言:你写的不是智能体,是适配层

做 AI 应用有个现实:你以为你在写业务,最后写出来的大半却是“让模型能稳定跑起来”的适配层。
今天接 A 家,明天换 B 家试效果;SDK、鉴权、错误码、流式细节、工具调用格式都不一样。你越想多接几家,项目越容易被胶水代码包住:能跑,但每次改动都得小心翼翼。

如果你要的只是 Demo,硬怼也行;但如果你要的是能长期跑的自动化流程(比如:定时采集信息 → 归档 → 总结 → 生成报告 → 分发),你需要把“模型”从代码里解耦出来:让模型像数据库/缓存一样,是可替换的资源,而不是写死在业务里。

下面我用 OpenClaw + 147AI 这个组合,讲清楚怎么把调度权收回来:业务代码只面对一种口径,模型怎么换、怎么兜底交给配置和网关。


第一章:为什么多模型项目最容易变成一团适配代码?

问题不在“你接了几家模型”,而在于耦合点放错了位置。常见会卡在这几处:

  • SDK 与请求结构:每接一家模型就多一套 client、多一份参数与返回结构的假设;一旦要迁移或做 AB 实验,改动面会从“一个调用点”扩散成“一片文件”。
  • 认证与额度:Key 分散、轮换难;某个渠道限流或风控时,业务层很难优雅降级。
  • 运行时行为:流式、超时、重试、并发、工具调用等细节不一致,你不得不把“兼容逻辑”塞进业务代码里。

结果就是:业务逻辑没复杂多少,适配层先膨胀了。你一换模型,改的不只是 model=,还有一串你原本不想维护的边角行为。


第二章:147AI:先把调用口径统一,再谈模型选择

把模型从业务里抽出去,最直接的办法是引入统一网关:应用只面向一种接口形态,至于背后路由到哪家模型、用哪个 Key、怎么做限流与兜底,尽量交给网关/配置层。

关于 147AI,官网首页的页面描述(meta description)写明它用于 OpenAI 接口的聚合管理,支持包括 Azure 在内的多种渠道,并提供单可执行文件与 Docker 镜像,主打“一键部署”(来源:147ai.com)。从接口路径命名也能看出它沿用 OpenAI 的 /v1/... 形态:例如对 https://147ai.com/v1/chat/completions 发起不带授权的请求会返回 401,响应里会提示“未提供令牌”。

这意味着你可以把整体链路变成这样:

业务代码 / 自动化任务
        ↓
OpenClaw(负责任务编排与执行)
        ↓
147AI(统一 OpenAI 风格入口:/v1/...)
        ↓
不同模型能力(文本 / 推理 / 多模态等,以你在 147AI 中实际可用的为准)

入口一旦收敛,业务侧通常只需要关心两件事:base_url 指向哪里、model 选哪个。SDK 映射、账号/Key 管理,以及一些兜底策略(比如 fallback、重试、轮换)就有机会从业务代码里抽出来。


第三章:实战:用 OpenClaw 组织流程,把 147AI 当作 Provider

OpenClaw 是一个开源 AI 助手/网关,支持用配置把“模型选择、fallback、工具与渠道”组织起来(项目地址:openclaw/openclaw;文档:OpenClaw Docs)。

这章只做一件事:让 OpenClaw 把 147AI 当成一个 OpenAI 风格 Provider(对应 OpenClaw 里的 openai-completions 协议)。之后你要换模型,很多时候只是改一个 provider/model-id 字符串。

1)先跑通 OpenClaw 的配置入口

OpenClaw 的网关配置文件默认在 ~/.openclaw/openclaw.json,格式是 JSON5(支持注释与尾逗号)。更省事的方式是先跑一遍向导(参考:Configuration):

openclaw onboard

2)把 147AI 配成一个 Provider(OpenAI 风格)

OpenClaw 的 Provider 允许你自定义 baseUrlapiKey 以及 API 协议类型(例如 openai-completions)。下面这段写法沿用 OpenClaw 的“Model Providers”文档结构(参考:Model Providers),把 Provider 名字起成 api147

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

  agents: {
    defaults: {
      model: {
        primary: "api147/your-model-id",
        fallbacks: ["api147/your-fallback-model-id"],
      },
      models: {
        "api147/your-model-id": { alias: "主力" },
        "api147/your-fallback-model-id": { alias: "兜底" },
      },
    },
  },
}

然后在运行 OpenClaw 之前,把 Key 放进环境变量里(示例):

export API147_KEY="你的 147AI Key"

到这里,你就把“模型接入”从业务代码里挪到了 OpenClaw 配置层:后面要换模型,只需要换 api147/<model-id>

补一条很实用的坑:如果你把 agents.defaults.models 当成 allowlist(允许列表)启用了,但没把 api147/<model-id> 加进去,聊天里切模型会提示 “Model is not allowed”。这个行为在官方文档里有说明(参考:Models CLI)。


第四章:多模型落地最难的一关:稳定性

生产环境里,最难的从来不是“能不能调用”,而是“遇到抖动时能不能稳住”。
OpenClaw 的失败处理有两层:模型 fallback(agents.defaults.model.fallbacks)与同一 Provider 内的鉴权档案轮换(参考:Model Failover)。

你可以先用很朴素的策略把系统扛住:

  • 先准备一主一备两档模型。主力追求效果,兜底保证可用。
  • 让业务只关心“拿到结果/拿不到结果”,把重试、冷却、轮换放在网关与配置层。
  • 日志里至少带上 model、耗时、错误类型。线上抖动时,这些信息能救命。

这件事看起来“很脏”,但它决定你的系统能不能持续跑。


第五章:接入 Flux / Sora 这类多模态模型时,别踩这几个坑

多模态的坑不在“调用一次接口”,而在 任务形态:图片、视频、音频通常更重、更慢、更依赖队列/存储,和普通文本请求不是一回事。

OpenClaw 里可以单独指定 agents.defaults.imageModel,用来处理主模型无法接收图片输入时的自动切换(参考:Models CLI)。

1. Flux:别把“重模型”当“轻接口”

文生图/图生图往往对输入、分辨率、并发更敏感。建议你至少做到两点:

  • 把图片模型单独挂在 agents.defaults.imageModel,不要和文本模型混用同一个默认位。
  • 把“上传/存储/回传图片链接”当成流程的一部分设计,而不是临时在代码里拼接。

2. Sora 类视频生成:把一次调用当成一个任务

视频生成更像“作业系统”,不是传统的“请求-响应”。

  • 异步优先。即便接口支持同步返回,架构上也按异步任务来做(队列、状态机、超时与取消)。
  • 让流程可重放。把输入参数与版本记下来,别让问题变成“复现不了的玄学”。
  • 做分层兜底。失败时先降级分辨率/时长,再降级模型,最后再给用户明确反馈。

这些都和“选哪家模型”无关,但决定你能不能把多模态真正做成产品。


第六章:代码实战(Python 示例)

如果你不想先引入 OpenClaw,只想先做连通性验证,可以用 OpenAI Python SDK 的 base_url 方式尝试直连 https://147ai.com/v1(不带授权请求会返回 401,这一点前面已经提到)。

from openai import OpenAI

client = OpenAI(
    api_key="你的 147AI Key",
    base_url="https://147ai.com/v1",
)

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

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

复制代码前,建议先看这几个点:

  • base_url 通常以 /v1 结尾。
  • model 的具体 ID 以 147AI 的控制台/文档为准。
  • 如果返回 401 且提示“未提供令牌”,大概率是 Key/令牌没带上或无效。
  • OpenAI SDK 默认用 Authorization: Bearer <api_key> 方式携带令牌。
  • 如果你通过 OpenClaw 切模型遇到 “Model is not allowed”,回去检查 agents.defaults.models 的 allowlist 设置。

当你把 base_urlmodel 参数抽出来,切换模型就会变成“改配置”。


第七章:给架构师和开发者的建议

我更愿意把“统一网关”当成一条底线:你不一定一开始就用得很复杂,但最好从第一天就把路走对。

  • 把模型当成依赖项,而不是写死的业务逻辑。业务层不关心供应商,只关心能力与返回结构。
  • 把可用性当成功能的一部分。超时、重试、fallback、限流策略,最好有明确的默认值。
  • 别迷信单一最强模型。真实系统里更常见的是“主力效果 + 兜底可用性”的组合。
  • 先把可观测性补齐。只要不记录 model 与耗时,后面做成本控制和稳定性优化就会很痛。

结语

这篇文章从头到尾只想落实标题里的两件事:统一网关和流水线。
OpenClaw 负责把任务拆开、串起来,147AI 负责把模型调用收敛到一个 OpenAI 风格入口。入口统一之后,你就能把时间花在流程本身:数据怎么来、怎么清洗、怎么评估产出,而不是不停地改 SDK 和适配细节。


附录:主流 AI 模型与 147AI 配合表

下面这张表不假设任何“你一定能用到某个具体模型”。它只给一个工程化的对照:你要的能力是什么、在 OpenClaw 里应该放在哪个配置位、以及在 147AI 侧你需要确认哪些信息(模型 ID、是否支持流式、是否支持多模态等)。

你要的能力 常见落点(OpenClaw) 147AI 侧你需要确认 备注
日常对话/写作 agents.defaults.model.primary 可用的文本模型 ID;是否支持流式输出 先选一个“稳定”模型做主力
复杂推理/规划 agents.defaults.model.fallbacks(或另设 agent) 是否有更擅长推理的模型;是否有更高延迟 推理模型适合做“按需调用”
图片输入/图片生成 agents.defaults.imageModel.primary 图片模型 ID;输入输出格式;是否需要图片 URL 把存储/回传当流程设计
视频生成(Sora 类) 通常做成工具/任务,不建议当同步对话模型 是否支持异步;任务状态查询方式 关键在队列与状态机
Embeddings / 向量化 取决于你是否有对应端点与工具链 是否提供兼容的 embeddings 端点(如 /v1/embeddings 没有就单独接一套也行
← 返回博客列表