OptiWaves

使用 SDK 开发

通过 TypeScript 与 AI SDK、OpenAI SDK 或 Anthropic SDK,把 OptiWaves 接入自己的应用。

使用通用 SDK 即可接入 OptiWaves。下面使用 TypeScript 与 Node.js,从配置环境开始,分别演示生成文本、流式输出和读取用量;选择与你的项目一致的一条路径即可。

选择 SDK

SDK适合的项目本页使用的协议
AI SDK使用 generateText、streamText 构建应用,或需要统一多个模型提供商Responses
OpenAI SDK已使用 openai 包,或希望直接处理 Responses 对象与事件Responses;兼容 Chat Completions
Anthropic SDK已使用 @anthropic-ai/sdk 和 Messages 接口Anthropic Messages

1. 准备项目与配置

使用 Node.js 22 或以上版本,建议使用 Node.js 24 LTS。在新目录中初始化项目:

mkdir optiwaves-example
cd optiwaves-example
npm init -y
npm pkg set type=module "scripts.typecheck=tsc --noEmit"
npm install -D typescript tsx @types/node@22

在项目根目录新建 tsconfig.json,启用严格类型检查:

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "noEmit": true,
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "types": ["node"]
  },
  "include": ["*.ts"]
}

本页通过 tsx 运行 TypeScript,使用 tsc --noEmit 检查类型。allowImportingTsExtensions 允许示例直接导入 ./config.ts。已有 TypeScript 项目可以沿用自己的配置、目录结构和运行方式。

在 API 密钥创建密钥。在项目根目录新建 .env,将占位值替换为自己的密钥:

.env
OPTIWAVES_API_KEY=ow_your_api_key_here
OPTIWAVES_MODEL=auto

将 .env 加入 .gitignore。这些示例在服务端运行;密钥不放入浏览器代码,也不要使用 NEXT_PUBLIC_ 或 VITE_ 前缀公开它。

新建共享配置文件,后面的示例均从这里读取连接信息:

config.ts
const envApiKey = process.env.OPTIWAVES_API_KEY;

if (!envApiKey) {
  throw new Error('请设置 OPTIWAVES_API_KEY,并使用 --env-file=.env 启动。');
}

export const apiKey: string = envApiKey;
export const modelId = process.env.OPTIWAVES_MODEL || 'auto';
export const baseURL = 'https://api.optiwaves.app/v1';

安装与你选择的 SDK 对应的依赖即可,无需安装全部 SDK。保存对应章节的示例后,先检查类型,再按该章节的命令运行:

npm run typecheck

检查成功时命令正常退出,没有类型错误输出。tsx 本身不执行类型检查。

2. 使用 AI SDK

安装 AI SDK 7 与 OpenAI provider 4:

npm install ai@7 @ai-sdk/openai@4
npm install -D @types/json-schema

通过 createOpenAI 指定 OptiWaves 地址,并显式选择 .responses(modelId)。这是 AI SDK OpenAI provider 的自定义连接方式。

生成文本

ai-sdk.ts
import { generateText } from 'ai';
import { createOpenAI } from '@ai-sdk/openai';
import { apiKey, baseURL, modelId } from './config.ts';

const optiwaves = createOpenAI({ apiKey, baseURL });

const result = await generateText({
  model: optiwaves.responses(modelId),
  prompt: '用三点说明流式输出适合哪些应用场景。',
  maxOutputTokens: 1024,
  maxRetries: 0,
  providerOptions: { openai: { store: false } },
});

console.log(result.text);
console.log(result.usage);

运行:

npx tsx --env-file=.env ai-sdk.ts

result.text 是正文,result.usage 是 token 用量。需要多轮对话时,由应用在每次请求中发送历史消息。

流式输出

新建另一个文件,将文本片段持续输出到终端:

ai-sdk-stream.ts
import { streamText } from 'ai';
import { createOpenAI } from '@ai-sdk/openai';
import { apiKey, baseURL, modelId } from './config.ts';

const optiwaves = createOpenAI({ apiKey, baseURL });
const result = streamText({
  model: optiwaves.responses(modelId),
  prompt: '用三点说明流式输出适合哪些应用场景。',
  maxOutputTokens: 1024,
  maxRetries: 0,
  providerOptions: { openai: { store: false } },
  onError() {
    process.exitCode = 1;
    console.error('生成失败,请检查密钥、额度与请求参数。');
  },
});

for await (const text of result.textStream) {
  process.stdout.write(text);
}
console.log('\n用量:', await result.usage);
npx tsx --env-file=.env ai-sdk-stream.ts

必须消费流才能取得完整结果;流中的失败通过 onError 处理。更多返回值见 AI SDK 文本与流式生成。

3. 使用 OpenAI SDK

安装 OpenAI SDK:

npm install openai@7

生成文本

openai-sdk.ts
import OpenAI from 'openai';
import { apiKey, baseURL, modelId } from './config.ts';

const client = new OpenAI({ apiKey, baseURL, maxRetries: 0 });
const response = await client.responses.create({
  model: modelId,
  input: '用三点说明流式输出适合哪些应用场景。',
  max_output_tokens: 1024,
  store: false,
});

if (response.status !== 'completed') {
  throw new Error(`生成未完成:${response.status}`);
}
console.log(response.output_text);
console.log(response.usage);
npx tsx --env-file=.env openai-sdk.ts

response.output_text 是 SDK 汇总的正文,response.usage 包含输入和输出 token。baseURL 必须指向 OptiWaves,apiKey 必须显式使用你的 OptiWaves 密钥。SDK 的基础用法见 OpenAI 开发入门。

流式输出

openai-sdk-stream.ts
import OpenAI from 'openai';
import { apiKey, baseURL, modelId } from './config.ts';

const client = new OpenAI({ apiKey, baseURL, maxRetries: 0 });
const stream = client.responses.stream({
  model: modelId,
  input: '用三点说明流式输出适合哪些应用场景。',
  max_output_tokens: 1024,
  store: false,
});

for await (const event of stream) {
  if (event.type === 'response.output_text.delta') {
    process.stdout.write(event.delta);
  }
}

const response = await stream.finalResponse();
if (response.status !== 'completed') {
  throw new Error(`生成未完成:${response.status}`);
}
console.log('\n用量:', response.usage);
npx tsx --env-file=.env openai-sdk-stream.ts

读取最终响应后再确认成功,不能仅凭连接关闭判断生成完成。事件说明见 OpenAI 流式响应和 OptiWaves Responses 参考。

已有项目使用 Chat Completions

保留上面的 client 配置,把调用替换为:

const completion = await client.chat.completions.create({
  model: modelId,
  messages: [{ role: 'user', content: '用三点说明流式输出适合哪些应用场景。' }],
  max_tokens: 1024,
});

console.log(completion.choices[0]?.message.content);
console.log(completion.usage);

这里继续使用带 /v1 的 baseURL。字段与流式格式见 Chat Completions 参考。

4. 使用 Anthropic SDK

已有 Messages 项目可以保留 SDK,修改地址、密钥和模型:

npm install @anthropic-ai/sdk
anthropic-sdk.ts
import Anthropic from '@anthropic-ai/sdk';
import { apiKey, modelId } from './config.ts';

const client = new Anthropic({
  apiKey,
  authToken: null,
  baseURL: 'https://api.optiwaves.app',
  maxRetries: 0,
});

const message = await client.messages.create({
  model: modelId,
  messages: [{ role: 'user', content: '用三点说明流式输出适合哪些应用场景。' }],
  max_tokens: 1024,
});

for (const block of message.content) {
  if (block.type === 'text') console.log(block.text);
}
console.log(message.usage);
npx tsx --env-file=.env anthropic-sdk.ts

Anthropic SDK 的 baseURL 不带 /v1,SDK 会追加 /v1/messages。authToken: null 避免已有 Anthropic token 环境变量与 API Key 同时发送。SDK 支持的语言见 Anthropic 客户端 SDK,请求参数见 Messages 参考。

5. 接入自己的应用

下面做一个能在浏览器中提问的小应用:网页把问题发送到你自己的 /api/chat,Express 服务端通过 OpenAI SDK 调用 OptiWaves,再把回答显示到网页。

沿用第 1 步的 .env 和 config.ts,在同一个项目目录安装依赖:

npm install express@5 openai@7
npm install -D @types/express@5
mkdir public

服务端

在项目根目录创建 server.ts:

server.ts
import express, { type Request, type Response } from 'express';
import OpenAI from 'openai';
import { apiKey, baseURL, modelId } from './config.ts';

const app = express();
const client = new OpenAI({ apiKey, baseURL, maxRetries: 0, timeout: 60000 });

app.use(express.json({ limit: '16kb' }));
app.use(express.static('public'));

type ChatResponse = { answer: string } | { error: string };
type ChatRequest = Request<Record<string, never>, ChatResponse, unknown>;

app.post('/api/chat', async (req: ChatRequest, res: Response<ChatResponse>) => {
  const body = req.body;
  const question = typeof body === 'object' && body !== null
    && 'question' in body && typeof body.question === 'string'
    ? body.question.trim()
    : '';
  if (!question || question.length > 2000) {
    return res.status(400).json({ error: '请输入 1 到 2000 字的问题' });
  }

  try {
    const response = await client.responses.create({
      model: modelId,
      input: question,
      max_output_tokens: 2048,
      store: false,
    });
    if (response.status !== 'completed' || !response.output_text) {
      return res.status(502).json({ error: '回答未完成 请重试' });
    }
    res.json({ answer: response.output_text });
  } catch {
    res.status(502).json({ error: '生成失败 请检查 API Key 和可用额度后重试' });
  }
});

app.listen(3001, '127.0.0.1', () => {
  console.log('打开 http://127.0.0.1:3001');
});

网页

创建 public/index.html:

public/index.html
<!doctype html>
<html lang="zh-CN">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>OptiWaves 问答示例</title>
  <h1>向 OptiWaves 提问</h1>
  <form id="chat">
    <label for="question">问题</label>
    <textarea id="question" required maxlength="2000" rows="4"></textarea>
    <button type="submit">发送</button>
  </form>
  <p id="answer" role="status" style="white-space: pre-wrap"></p>
  <script type="module">
    const form = document.querySelector('#chat');
    const question = document.querySelector('#question');
    const button = form.querySelector('button');
    const answer = document.querySelector('#answer');

    form.addEventListener('submit', async (event) => {
      event.preventDefault();
      button.disabled = true;
      answer.textContent = '正在生成';
      try {
        const response = await fetch('/api/chat', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ question: question.value }),
        });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || '请求失败');
        answer.textContent = data.answer;
      } catch (error) {
        answer.textContent = error.message || '请求失败 请重试';
      } finally {
        button.disabled = false;
      }
    });
  </script>
</html>

启动并提问

在项目根目录检查类型并启动:

npm run typecheck
npx tsx --env-file=.env server.ts

打开 http://127.0.0.1:3001,输入“用一句话解释什么是 API”,点击 发送。页面先显示“正在生成”,收到响应后显示模型回答。

API Key 只由服务端读取,浏览器调用的是你自己的 /api/chat。这个示例每次处理一个问题;需要连续对话时,再将历史消息加入 input。部署给其他用户前,在这个接口接入你应用的登录校验和用量限制。

售后群 1055897442

本页