集成使用集成调用 OpenAI 模型

使用集成调用 OpenAI 模型

连接 OpenAI 集成后在 Func 里用 ctx.ai.openai 调模型:chat 做对话与翻译,json 让模型稳定输出结构化数据,tools 做单次工具调用,image 生成图片并存进项目空间。API Key 只保存在服务端。

连接 OpenAI 集成之后,Func 里用 ctx.ai.openai 就能调模型:对话、翻译、抽取结构化数据、调用一次工具、生成图片。API Key 只保存在服务端,代码里不会出现。

连接 OpenAI

打开编辑器的后端 → 集成,点 OpenAI,按下表填写。保存时平台会真的打一次上游,密钥不对当场报错,而不是等到有人用到这个功能才发现。

字段填什么必填
API Keysk- 开头的密钥,在 OpenAI 后台创建
默认模型调用没指定模型时用它,比如 gpt-4o-mini建议
接口地址留空就是 https://api.openai.com/v1。填别家兼容地址即可换供应商
渠道标签同一个项目可以接多份配置,用标签区分,见多渠道

chat:一次对话

ctx.ai.openai.chat(params) 发一次调用并返回完整结果。

export function translate(input, ctx) {
  const r = ctx.ai.openai.chat({
    messages: [
      { role: 'system', content: '把用户输入翻译成英文,只输出译文' },
      { role: 'user', content: input.text },
    ],
    model: 'gpt-4o-mini',   // 不传就用集成里配的默认模型
    temperature: 0.2,
    maxTokens: 512,
  })
  return { text: r.content, tokens: r.totalTokens }
}
参数说明
messages必填。{ role, content } 数组,rolesystem / user / assistant / developer / tool
model留空取集成里配的默认模型
temperature不传就不发这个字段
maxTokens不传就不发这个字段
jsontrue 时平台剥代码块并解析,结果放进 data,见要 JSON
tools / toolChoice工具定义,见单次 tool call
extra逃生舱,原样并进请求体,见逃生舱

返回:

字段说明
content模型回复的文本。只要求调用工具时它是空的,这不是错误
model实际用到的模型
finishReasonstop / length / tool_calls
promptTokens / completionTokens / totalTokens用量,方便自己记账
data只有 json: true 时才有
toolCalls只有模型要求调用工具时才有

要 JSON 就传 json: true

让模型输出 JSON 是这个能力最常见的用法:翻译、抽取、分类全是。json: true 时平台会剥掉模型爱包的代码块再解析,结果放在 data 里。

export function extract(input, ctx) {
  const r = ctx.ai.openai.chat({
    messages: [{ role: 'user', content: `从这段话里抽出姓名和城市,返回 JSON:${input.text}` }],
    json: true,
  })
  return { name: r.data.name, city: r.data.city }
}

单次 tool call

tools,模型要调工具时 toolCalls 里就有东西。典型用法是一轮:把用户的自然语言变成一次结构化的函数调用,站点自己执行,然后直接回话。

export function assistant(input, ctx) {
  const r = ctx.ai.openai.chat({
    messages: [{ role: 'user', content: input.text }],
    tools: [{
      type: 'function',
      function: {
        name: 'reschedule',
        description: '把一个会议改期',
        parameters: {
          type: 'object',
          properties: { meetingId: { type: 'string' }, date: { type: 'string' } },
          required: ['meetingId', 'date'],
        },
      },
    }],
    toolChoice: 'auto',
  })

  if (r.toolCalls?.length) {
    const c = r.toolCalls[0]
    // c.arguments 已经是对象
    ctx.db.update('meetings', c.arguments.meetingId, { date: c.arguments.date })
    return { done: true }
  }
  return { reply: r.content }
}
toolCalls[i]说明
id这次调用的 id。要跑第二轮的话得把它带回去
name模型要调的函数名
arguments已经解析好的对象。模型吐出坏 JSON 时它是 undefined
argumentsRaw参数原文,永远都在

想跑第二轮(执行完工具再让模型总结)也可以,把工具结果拼回 messages 再调一次即可:

const r2 = ctx.ai.openai.chat({
  messages: [
    { role: 'user', content: input.text },
    { role: 'assistant', toolCalls: r.toolCalls },              // 回放模型上一轮的要求
    { role: 'tool', toolCallId: r.toolCalls[0].id, content: JSON.stringify(result) },
  ],
})

平台不替你跑这个循环:几轮停、工具能不能读数据库、超时怎么算,只有站点自己知道。

生成图片

ctx.ai.openai.image(params)强烈建议带 upload: true,图片会直接存进项目自己的空间并返回永久地址。

export const config = { timeoutMs: 120000 }   // 生图慢,几十秒是常态

export function cover(input, ctx) {
  const r = ctx.ai.openai.image({
    prompt: input.prompt,
    size: '1024x1024',
    quality: 'high',
    upload: true,
  })
  return { url: r.images[0].fileUrl }
}
参数说明
prompt必填。只传一个字符串也行:image('一只雪地里的红狐狸,水彩')
model默认 gpt-image-1不会用集成里配的对话模型,那是两回事
size1024x10241536x1024
qualitylow / medium / high;dall-e-3 是 standard / hd
styledall-e-3 专有:vivid / natural
backgroundgpt-image-1 专有:transparent / opaque / auto
n张数,最多 4
uploadtrue 时存进项目空间并返回 fileUrl;不传则返回 imageBase64
filename只在 upload 时有用。默认按内容哈希命名

返回 { model, images: [...] },每张图是 { fileUrl | imageBase64, mimeType, bytes, revisedPrompt? }

逃生舱:extra 与 call

想传平台没暴露的字段,用 extra。它原样并进请求体,但改不坏 messages

ctx.ai.openai.chat({
  messages,
  extra: { top_p: 0.9, seed: 42, response_format: { type: 'json_object' } },
})

想调 /chat/completions 之外的接口,用 call(path, body)。请求体原样发出,上游返回的 JSON 原样交回,密钥同样不进沙箱:

const r = ctx.ai.openai.call('/embeddings', {
  model: 'text-embedding-3-small',
  input: input.text,
})
const vector = r.data[0].embedding

多渠道:via(tag)

一个项目可以接多份 OpenAI 配置,比如分类用便宜模型、写作用强模型,或者一份官方一份自建网关。给每份配置写上渠道标签,代码里用 via() 选:

ctx.ai.openai.via('cheap').chat({ messages })
ctx.ai.openai.via('strong').chat({ messages })

不写 via() 时用标签为 default 的那份。

报错怎么看

报错该改哪一项
ai integration has no api key集成没连,或密钥被清空了
model is required调用没传 model,集成里也没配默认模型
message at index N has empty content有一条消息的 content 是空的
message at index N has role tool but no toolCallId跑第二轮时忘了带 toolCallId
ai response is not valid json用了 json: true 但模型没给 JSON。报错里带原文片段,先看是提示词没说清楚还是模型跑偏
the image provider returned a temporary url网关没按要求返回图片字节。改用 call() 自己处理,或换一个支持 b64_json 的网关
invalid n一次最多 4 张

上游自己的报错(额度用完、模型不存在、速率限制)会原样带上文案转成 400 或 502。不会把上游的 401 直接抛给前端,那会让页面误以为是没登录。

不做的事

不做为什么
多轮 agent 循环停机条件、轮数预算、工具权限只有站点自己知道。单次 tool call 有,循环自己写
流式输出Func 的返回值本来就是一次性的。要打字机效果用 ctx.sse 自己推
缓存与去重「什么算同一次请求」只有站点知道。要缓存自己建一张表
并入平台积分这是你自己的 API Key、你自己的账单,平台不插手计费

相关文档:更多集成语音合成集成Func 后端能力

Render diagnostics