ข้ามไปเนื้อหาหลัก

Category: guide

Claude API & Anthropic SDK

ใช้งาน Anthropic SDK กับ TypeScript: Messages API, streaming, tool use (function calling), system prompts, token counting และ best practices

· อ่านประมาณ 3 นาที

สารบัญ

Setup

npm install @anthropic-ai/sdk
// .env
ANTHROPIC_API_KEY=sk-ant-...

// client.ts
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

Basic Message

const message = await client.messages.create({
  model: 'claude-sonnet-4-6',
  max_tokens: 1024,
  messages: [
    { role: 'user', content: 'อธิบาย OEM vs aftermarket parts ให้กระชับ' }
  ],
});

console.log(message.content[0].text);
// message.stop_reason: 'end_turn' | 'max_tokens' | 'tool_use'
// message.usage: { input_tokens, output_tokens }

System Prompt

const message = await client.messages.create({
  model: 'claude-sonnet-4-6',
  max_tokens: 512,
  system: `คุณเป็น copywriter สำหรับ e-commerce อะไหล่มอเตอร์ไซค์
ตอบภาษาไทย สั้น กระชับ ไม่เกิน 100 คำต่อ description
ถ้าข้อมูลเทคนิคไม่พอ ให้ถามแทนการเดา`,
  messages: [
    { role: 'user', content: 'เขียน description สำหรับ: ปลอกแฮนด์ Renthal 22mm ลายเพชร' }
  ],
});

Multi-turn Conversation

const history: Anthropic.MessageParam[] = [];

async function chat(userMessage: string): Promise<string> {
  history.push({ role: 'user', content: userMessage });

  const response = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 1024,
    system: 'คุณเป็น assistant ช่วยเรื่อง e-commerce อะไหล่มอเตอร์ไซค์',
    messages: history,
  });

  const assistantMessage = response.content[0].text;
  history.push({ role: 'assistant', content: assistantMessage });
  return assistantMessage;
}

await chat('สินค้านี้เหมาะกับใคร: โช้คหลัง YSS G-Sport');
await chat('แล้วถ้าใช้บนถนนในเมืองทุกวันล่ะ?');

Streaming

const stream = await client.messages.stream({
  model: 'claude-sonnet-4-6',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'เขียน product description ยาว 300 คำ' }],
});

// ดู token ทีละ chunk
for await (const chunk of stream) {
  if (chunk.type === 'content_block_delta' && chunk.delta.type === 'text_delta') {
    process.stdout.write(chunk.delta.text);
  }
}

const finalMessage = await stream.finalMessage();
console.log('Tokens:', finalMessage.usage);

Tool Use (Function Calling)

const tools: Anthropic.Tool[] = [
  {
    name: 'get_product_info',
    description: 'ดึงข้อมูลสินค้าจาก database โดยใช้ part number',
    input_schema: {
      type: 'object',
      properties: {
        part_number: { type: 'string', description: 'Part number ของสินค้า เช่น KYB-341866' },
      },
      required: ['part_number'],
    },
  },
];

// ส่ง tools ไป
const response = await client.messages.create({
  model: 'claude-sonnet-4-6',
  max_tokens: 1024,
  tools,
  messages: [{ role: 'user', content: 'ดูข้อมูลสินค้า KYB-341866 แล้วเขียน description' }],
});

// Claude เรียก tool
if (response.stop_reason === 'tool_use') {
  const toolUse = response.content.find((b) => b.type === 'tool_use');
  if (toolUse?.type === 'tool_use') {
    const input = toolUse.input as { part_number: string };
    const productData = await getProductFromDB(input.part_number);

    // ส่งผลลัพธ์ tool กลับไป
    const followUp = await client.messages.create({
      model: 'claude-sonnet-4-6',
      max_tokens: 1024,
      tools,
      messages: [
        { role: 'user', content: 'ดูข้อมูลสินค้า KYB-341866 แล้วเขียน description' },
        { role: 'assistant', content: response.content },
        {
          role: 'user',
          content: [{
            type: 'tool_result',
            tool_use_id: toolUse.id,
            content: JSON.stringify(productData),
          }],
        },
      ],
    });
    console.log(followUp.content[0].text);
  }
}

Structured Output ด้วย Tool

// บังคับ JSON output ด้วย tool_choice
const response = await client.messages.create({
  model: 'claude-sonnet-4-6',
  max_tokens: 512,
  tools: [{
    name: 'output_product_data',
    description: 'Output ข้อมูลสินค้าในรูปแบบ structured',
    input_schema: {
      type: 'object',
      properties: {
        name: { type: 'string' },
        category: { type: 'string', enum: ['engine', 'brake', 'suspension', 'electrical'] },
        description_th: { type: 'string' },
        tags: { type: 'array', items: { type: 'string' } },
      },
      required: ['name', 'category', 'description_th', 'tags'],
    },
  }],
  tool_choice: { type: 'tool', name: 'output_product_data' },
  messages: [{ role: 'user', content: 'วิเคราะห์: ปลอกแฮนด์ Renthal Fat Bar 22mm สีดำ' }],
});

const toolUse = response.content[0];
if (toolUse.type === 'tool_use') {
  const data = toolUse.input; // typed JSON
  console.log(data);
}

Token Counting & Cost

// Count tokens ก่อนส่ง
const tokenCount = await client.messages.countTokens({
  model: 'claude-sonnet-4-6',
  messages: [{ role: 'user', content: longPrompt }],
});
console.log(tokenCount.input_tokens); // ตรวจก่อนว่าเกิน budget หรือไม่

// Claude Sonnet 4.6 pricing (approx):
// Input:  $3 / 1M tokens
// Output: $15 / 1M tokens

Error Handling

import Anthropic from '@anthropic-ai/sdk';

try {
  const response = await client.messages.create({ ... });
} catch (error) {
  if (error instanceof Anthropic.APIError) {
    if (error.status === 429) console.log('Rate limit — retry after delay');
    if (error.status === 529) console.log('API overloaded — try again');
    if (error.status === 400) console.log('Bad request:', error.message);
  }
}

// Auto-retry ด้วย exponential backoff
const client = new Anthropic({
  maxRetries: 3,  // retry อัตโนมัติ
});