Skip to content

Node.js 示例

使用 OpenAI 官方 Node SDK,base_url 指向 kukuai.fyi 即可。给出同步、流式、function calling、退避重试与 Next.js Edge 路由模板。

使用 OpenAI 官方 Node SDK,base_url 指向 kukuai.fyi 即可。给出同步、流式、function calling、退避重试与 Next.js Edge 路由模板。

将代码中的 process.env.KUKUAI_API_KEY 指向你在 https://kukuai.fyi 控制台「API Keys」页面创建的 Key(建议用环境变量而非硬编码)。

bash

npm i openai
# 或
pnpm add openai

基础调用

basic.tstypescript

// basic.ts
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://www.kukuai.fyi/api-proxy/china/v1",
  apiKey: process.env.KUKUAI_API_KEY,
});

const resp = await client.chat.completions.create({
  model: "claude-opus-4-7",
  messages: [
    { role: "system", content: "You are a concise assistant." },
    { role: "user", content: "用 30 字介绍 kukuai.fyi" },
  ],
  temperature: 0.7,
  max_tokens: 1024,
});

console.log(resp.choices[0].message.content);
console.log("usage:", resp.usage?.total_tokens, "tokens");

流式响应

stream.tstypescript

// stream.ts
const stream = await client.chat.completions.create({
  model: "claude-opus-4-7",
  stream: true,
  messages: [{ role: "user", content: "讲一个关于 API 网关的冷笑话" }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0].delta.content ?? "");
}
process.stdout.write("\n");

function calling

tools.tstypescript

// tools.ts
const tools = [{
  type: "function" as const,
  function: {
    name: "get_weather",
    description: "查询某个城市的当前天气",
    parameters: {
      type: "object",
      properties: { city: { type: "string" } },
      required: ["city"],
    },
  },
}];

const resp = await client.chat.completions.create({
  model: "claude-opus-4-7",
  messages: [{ role: "user", content: "上海现在几度?" }],
  tools,
  tool_choice: "auto",
});

const call = resp.choices[0].message.tool_calls?.[0];
if (call) {
  console.log("model wants:", call.function.name, call.function.arguments);
}

退避重试

retry.tstypescript

// retry.ts
import OpenAI, { APIError, RateLimitError } from "openai";

const client = new OpenAI({
  baseURL: "https://www.kukuai.fyi/api-proxy/china/v1",
  // SDK 默认会做有限重试;这里关掉走我们自己的策略
  maxRetries: 0,
});

async function callWithRetry(
  messages: { role: "user" | "system" | "assistant"; content: string }[],
  model = "claude-opus-4-7",
  maxRetries = 3,
) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.chat.completions.create({ model, messages });
    } catch (err) {
      if (err instanceof RateLimitError) {
        await sleep(2 ** attempt * 1000);
        continue;
      }
      if (err instanceof APIError && err.status >= 500) {
        await sleep(2 ** attempt * 1000);
        continue;
      }
      throw err;
    }
  }
  throw new Error("max retries exceeded");
}

const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));

错误类别与处理建议详见 错误码

Next.js Edge / serverless

在 Edge / serverless 函数中转发流式响应,是 React 应用最常见的接入方式:

app/api/chat/route.tstypescript

// app/api/chat/route.ts  (Next.js App Router 示例)
import OpenAI from "openai";

export const runtime = "edge"; // 也可以是 "nodejs"

const client = new OpenAI({
  baseURL: "https://www.kukuai.fyi/api-proxy/china/v1",
  apiKey: process.env.KUKUAI_API_KEY,
});

export async function POST(req: Request) {
  const { messages } = await req.json();

  const stream = await client.chat.completions.create({
    model: "claude-opus-4-7",
    stream: true,
    messages,
  });

  // 直接把 SSE 透传给前端
  const encoder = new TextEncoder();
  const body = new ReadableStream({
    async start(controller) {
      for await (const chunk of stream) {
        const delta = chunk.choices[0].delta.content ?? "";
        controller.enqueue(encoder.encode(delta));
      }
      controller.close();
    },
  });

  return new Response(body, {
    headers: { "content-type": "text/plain; charset=utf-8" },
  });
}

统一 API 网关 · OpenAI Compatible