Your First API Call: Chat and Streaming

AI Navigate Original / 5/16/2026

共有:

Key Points

  • Implement 3 basics: sync chat, streaming, multi-turn
  • Add system prompts; same patterns for OpenAI and Vercel AI SDK
  • Handle errors (429/401), retry with exponential backoff
  • Track token cost; complex patterns covered in practice chapter

Your First API Call

Once setup is done, implement the 3 basic patterns (sync chat, streaming, multi-turn).

1. Sync Chat (Minimal)

Send a question, receive the whole response, and return it.

import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();

const res = await client.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 1024,
  messages: [
    { role: "user", content: "Difference between TypeScript and JavaScript?" }
  ],
});

console.log(res.content[0].text);
console.log("Tokens used:", res.usage);

2. Streaming

Receive the response token by token. Better UX.

const stream = await client.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 1024,
  messages: [{ role: "user", content: "5 things to see in Tokyo" }],
  stream: true,
});

for await (const event of stream) {
  if (event.type === "content_block_delta") {
    process.stdout.write(event.delta.text);
  }
}

3. Multi-Turn Conversation

Stack past exchanges in messages.

const history = [
  { role: "user", content: "1 thing to see in Tokyo" },
  { role: "assistant", content: "Sensoji is recommended. Kaminarimon..." },
  { role: "user", content: "One more, a place fun even in rain" },
];

const res = await client.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 1024,
  messages: history,
});

System Prompt

const res = await client.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 1024,
  system: "You are a polite Japanese travel guide. Answer within 200 chars.",
  messages: [{ role: "user", content: "Things to see in Kyoto?" }],
});

For OpenAI

import OpenAI from "openai";
const client = new OpenAI();

const res = await client.chat.completions.create({
  model: "gpt-5.5",
  messages: [
    { role: "system", content: "In polite Japanese." },
    { role: "user", content: "Things to see in Kyoto?" },
  ],
});

console.log(res.choices[0].message.content);

Streaming

const stream = await client.chat.completions.create({
  model: "gpt-5.5",
  messages: [...],
  stream: true,
});

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

Vercel AI SDK (Common Across Providers)

import { streamText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";

const result = streamText({
  model: anthropic("claude-opus-4-7"),
  prompt: "5 things to see in Tokyo",
});

for await (const chunk of result.textStream) {
  process.stdout.write(chunk);
}

Error Handling

try {
  const res = await client.messages.create({...});
} catch (e) {
  if (e instanceof Anthropic.RateLimitError) {
    // 429: wait and retry
    await new Promise(r => setTimeout(r, 1000));
  } else if (e instanceof Anthropic.AuthenticationError) {
    // 401: confirm key
    console.error("API key invalid");
  } else {
    throw e;
  }
}

Retry Strategy

async function withRetry(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try { return await fn(); }
    catch (e) {
      if (i === maxRetries - 1) throw e;
      const wait = Math.pow(2, i) * 1000; // exponential backoff
      await new Promise(r => setTimeout(r, wait));
    }
  }
}

Cost Tracking

const res = await client.messages.create({...});
console.log({
  input: res.usage.input_tokens,
  output: res.usage.output_tokens,
  // rough cost calculation
});

Next Step

Once basics are done, more complex patterns (Tool Use, structured output, RAG) are in the practice chapter. To run a local LLM with Ollama, see the next article.