メインコンテンツへスキップ

チャットSDK

ChatSDK は、会話型 AI アプリケーションを簡単に構築できるようにする EKB Content Creator SDK のコア コンポーネントです。包括的なチャット管理、メッセージ処理、ストリーミング応答、ナレッジベースの統合を提供します。この記事では、SDK をインストールし、「クイック スタート」の例を使用してすぐに起動して実行する方法を学びます。さまざまな構成オプションを調べ、認証と、この SDK で使用できる中心的なメソッドについて学ぶことができます。使用例も見つかります

インストール​

npm install @odin-ai-staging/sdk

クイックスタート​

import { ChatSDK } from '@odin-ai-staging/sdk';

// Initialize the SDK
const chatSDK = new ChatSDK({
baseUrl: 'https://your-api-endpoint.com/',
projectId: 'your-project-id',
apiKey: 'your-api-key',
apiSecret: 'your-api-secret'
});

// Create a chat and send a message
async function quickExample() {
// Create a new chat
const chat = await chatSDK.createChat('My First Chat');

// Send a message
const response = await chatSDK.sendMessage('Hello, how can you help me?', {
chatId: chat.chat_id
});

console.log('AI Response:', response.message);
}

## 構成

ChatSDKConfig インターフェイス​

interface ChatSDKConfig {
baseUrl: string; // API endpoint URL
projectId: string; // Your project identifier
apiKey?: string; // API key for authentication
apiSecret?: string; // API secret for authentication
accessToken?: string; // Access token for web app usage
}

構成オプション​

  • baseUrl: API エンドポイントのベース URL
  • projectId: 一意のプロジェクト識別子
  • apiKey および apiSecret: サーバー側認証用
  • accessToken: クライアント側認証用 (Web アプリ)

認証​

ChatSDK は 2 つの認証方法をサポートしています。

API キー認証 (サーバー側)​

const chatSDK = new ChatSDK({
baseUrl: 'https://api.example.com/',
projectId: 'proj_123',
apiKey: 'your-api-key',
apiSecret: 'your-api-secret'
});

アクセストークン認証 (クライアント側)​

const chatSDK = new ChatSDK({
baseUrl: 'https://api.example.com/',
projectId: 'proj_123',
accessToken: 'your-access-token'
});

コアメソッド​

チャット管理​

createChat(name?, documentKeys?)​

新しいチャット会話を作成します。

async createChat(
name?: string, // Optional chat name (defaults to "Untitled")
documentKeys?: string[] // Optional document keys for knowledge base context
): Promise<CreateChatResponse>

例:

// Create a basic chat
const chat = await chatSDK.createChat('Customer Support Chat');

// Create a chat with knowledge base context
const chatWithDocs = await chatSDK.createChat(
'Product Documentation Chat',
['doc_key_1', 'doc_key_2']
);

listChats(cursor?, limit?)​

プロジェクト内のチャットのページ分割されたリストを取得します。

async listChats(
cursor?: number, // Optional cursor for pagination
limit?: number // Number of chats to return (default: 30, max: 100)
): Promise<ListChatsResponse>

例:

// Get first 10 chats
const chats = await chatSDK.listChats(undefined, 10);

// Get next page using cursor
if (chats.next_cursor) {
const nextPage = await chatSDK.listChats(chats.next_cursor, 10);
}

getChatHistory(chatId)​

完全なメッセージ履歴を含むチャットを取得します。

async getChatHistory(chatId: string): Promise<ChatHistoryResponse>

例:

const chatHistory = await chatSDK.getChatHistory('chat_123');
console.log('Messages:', chatHistory.messages);

deleteChat(chatId)​

チャットとそのすべてのメッセージを完全に削除します。

async deleteChat(chatId: string): Promise<void>

例:

await chatSDK.deleteChat('chat_123');

updateChatName(chatId, newName)​

既存のチャットの表示名を更新します。

async updateChatName(chatId: string, newName: string): Promise<void>

例:

await chatSDK.updateChatName('chat_123', 'Updated Chat Name');

メッセージの処理​

sendMessage(message, options?)​

メッセージを送信し、AI 応答を受け取ります。

async sendMessage(
message: string,
options?: SendMessageOptions
): Promise<SendMessageResponse>

SendMessageOptions:

interface SendMessageOptions {
chatId?: string; // Target chat ID
agentType?: AgentType; // Type of AI agent to use
agentId?: string; // Specific agent ID
documentKeys?: string[]; // Knowledge base documents
images?: File[]; // Image attachments
metadata?: Record<string, any>; // Custom metadata
modelName?: ModelName; // AI model to use
useKnowledgebase?: boolean; // Enable knowledge base
isTest?: boolean; // Test mode flag
googleSearch?: boolean; // Enable web search
formatInstructions?: string; // Response format guidance
ignoreChatHistory?: boolean; // Ignore conversation history
exampleJson?: string; // Example JSON for structured responses
skipStream?: boolean; // Disable streaming
}

例:

// Basic message
const response = await chatSDK.sendMessage('What is artificial intelligence?', {
chatId: 'chat_123'
});

// Advanced message with options
const advancedResponse = await chatSDK.sendMessage(
'Analyze this data and provide insights',
{
chatId: 'chat_123',
modelName: 'gpt-4o',
useKnowledgebase: true,
googleSearch: true,
formatInstructions: 'Provide response in bullet points'
}
);

sendFeedback(messageId, chatId, feedback)​

AI の応答に関するフィードバックを提供します。

async sendFeedback(
messageId: string,
chatId: string,
feedback: boolean // true = thumbs up, false = thumbs down
): Promise<void>

例:

// Positive feedback
await chatSDK.sendFeedback('msg_123', 'chat_123', true);

// Negative feedback
await chatSDK.sendFeedback('msg_123', 'chat_123', false);

ストリーミングのサポート​

sendMessageStream(message, options)​

リアルタイムのストリーミング応答でメッセージを送信します。

async sendMessageStream(
message: string,
options: SendMessageOptions & StreamCallbacks
): Promise<void>

ストリームコールバック:

interface StreamCallbacks {
onChunk?: (chunk: string) => void; // Text chunks
onMessageObject?: (messageObject: any) => void; // Structured data
onComplete?: (message: Message) => void; // Final message
onError?: (error: Error) => void; // Error handler
onChatNameUpdate?: (chatName: string) => void; // Chat name changes
onDocumentChunk?: (chunk: string) => void; // Document processing updates
onMessageEnd?: () => void; // Stream completion
}

例:

await chatSDK.sendMessageStream(
'Tell me about machine learning',
{
chatId: 'chat_123',
onChunk: (chunk) => {
// Display text as it streams in
console.log('Chunk:', chunk);
updateUI(chunk);
},
onComplete: (message) => {
console.log('Complete message:', message);
finalizeUI(message);
},
onError: (error) => {
console.error('Stream error:', error);
showError(error.message);
}
}
);

エラー処理​

SDK は、API 関連のエラーに対して APIError オブジェクトをスローします。

interface APIError {
message: string; // Error description
status: number; // HTTP status code
detail?: string; // Additional error details
}

例:

try {
const response = await chatSDK.sendMessage('Hello');
} catch (error) {
if (error instanceof APIError) {
console.error(`API Error ${error.status}: ${error.message}`);
if (error.detail) {
console.error('Details:', error.detail);
}
} else {
console.error('Unexpected error:', error);
}
}

例​

基本的なチャット アプリケーション​

この例では、EKB SDK を使用して、単純な非ストリーミング メッセージ交換を行う基本的なチャット アプリケーションを構築する方法を学習します。まず、環境変数 (ベース URL、プロジェクト ID、API キー、およびシークレット) から取得した API 資格情報を使用して ChatSDK を初期化する SimpleChatApp クラスを作成します。このクラスは、currentChatId を使用して現在のチャット セッションを追跡し、3 つの主要なメソッドを提供します。startNewChat() はカスタム名で新しいチャット会話を作成し、sendMessage() は AI にメッセージを送信して完全な応答を返します (チャットが存在しない場合は自動的に新しいチャットを作成します)。getChatList() は既存のチャット会話をすべて取得します。ストリーミング実装とは異なり、このアプローチは完全な AI 応答を待ってから表示するため、リアルタイムのトークンごとの更新が必要ない単純なユースケースに最適です。この例では GPT-4o-mini モデルを使用しており、会話フローの追跡に役立つコンソール ログ機能を備えたエラー処理が全体に含まれており、ストリーミング コールバックの複雑さを必要とせずに、基本的なチャットボット機能を構築するための簡単な基盤が提供されます。

import { ChatSDK } from '@odin-ai-staging/sdk';

class SimpleChatApp {
private chatSDK: ChatSDK;
private currentChatId?: string;

constructor() {
this.chatSDK = new ChatSDK({
baseUrl: process.env.API_BASE_URL,
projectId: process.env.PROJECT_ID,
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET
});
}

async startNewChat(name: string = 'New Chat') {
try {
const chat = await this.chatSDK.createChat(name);
this.currentChatId = chat.chat_id;
console.log(`Created chat: ${chat.name} (${chat.chat_id})`);
return chat;
} catch (error) {
console.error('Failed to create chat:', error);
throw error;
}
}

async sendMessage(message: string) {
if (!this.currentChatId) {
await this.startNewChat();
}

try {
const response = await this.chatSDK.sendMessage(message, {
chatId: this.currentChatId,
modelName: 'gpt-4o-mini'
});

console.log('User:', message);
console.log('AI:', response.message);

return response;
} catch (error) {
console.error('Failed to send message:', error);
throw error;
}
}

async getChatList() {
try {
const chats = await this.chatSDK.listChats();
return chats.chats;
} catch (error) {
console.error('Failed to get chat list:', error);
throw error;
}
}
}

// Usage
const app = new SimpleChatApp();
await app.sendMessage('Hello, how are you?');

リアルタイム更新によるストリーミング チャット​

この例では、EKB API に接続し、AI 応答をリアルタイムで表示するストリーミング チャット インターフェイスを構築する方法を学びます。まず、API 資格情報とメッセージが表示される HTML 要素への参照を使用して ChatSDK を初期化する StreamingChat クラスを作成します。 sendStreamingMessage() を使用してメッセージを送信する場合、ストリーミング応答が到着したときにそれを処理するコールバック ハンドラーをセットアップします。onChunk コールバックは、各テキストを UI にすぐに追加します (特徴的な「入力」効果を作成します)。一方、onMessageObject を使用すると、画像などのリッチ コンテンツを処理できます。また、onError を使用してエラー処理を実装し、onChatNameUpdate を使用してチャット タイトルを更新し、メッセージのストリーミングが終了したら onComplete を使用して親指を上げる/下げるフィードバック ボタンを追加します。この例では、画像を動的に表示し、AI 応答に関するユーザー フィードバックを収集し、ナレッジ ベース統合で GPT-4o を使用するようにチャットを構成する方法を示します。これにより、リアルタイム ストリーミング応答とインタラクティブ機能を備えた ChatGPT のようなインターフェイスを作成するために必要なものがすべて提供されます。

import { ChatSDK, StreamCallbacks } from '@odin-ai-staging/sdk';

class StreamingChat {
private chatSDK: ChatSDK;
private messageElement: HTMLElement;

constructor(messageElement: HTMLElement) {
this.messageElement = messageElement;
this.chatSDK = new ChatSDK({
baseUrl: 'https://your-api.com/',
projectId: 'your-project-id',
accessToken: 'your-access-token'
});
}

async sendStreamingMessage(message: string, chatId: string) {
// Clear previous content
this.messageElement.innerHTML = '';

const callbacks: StreamCallbacks = {
onChunk: (chunk: string) => {
// Append each chunk to the UI
this.messageElement.innerHTML += chunk;
this.messageElement.scrollIntoView();
},

onMessageObject: (messageObj: any) => {
// Handle structured data like images, cards, etc.
if (messageObj.image_urls) {
this.displayImages(messageObj.image_urls);
}
},

onComplete: (message: any) => {
console.log('Message complete:', message);
// Add final styling, enable feedback buttons, etc.
this.finalizeMessage(message);
},

onError: (error: Error) => {
console.error('Streaming error:', error);
this.messageElement.innerHTML = `Error: ${error.message}`;
},

onChatNameUpdate: (chatName: string) => {
// Update chat title in UI
document.title = chatName;
}
};

try {
await this.chatSDK.sendMessageStream(message, {
chatId,
modelName: 'gpt-4o',
useKnowledgebase: true,
...callbacks
});
} catch (error) {
console.error('Failed to send streaming message:', error);
}
}

private displayImages(imageUrls: string[]) {
imageUrls.forEach(url => {
const img = document.createElement('img');
img.src = url;
img.style.maxWidth = '100%';
this.messageElement.appendChild(img);
});
}

private finalizeMessage(message: any) {
// Add feedback buttons
const feedbackDiv = document.createElement('div');
feedbackDiv.innerHTML = `
<button onclick="this.provideFeedback('${message.id}', true)">👍</button>
<button onclick="this.provideFeedback('${message.id}', false)">👎</button>
`;
this.messageElement.appendChild(feedbackDiv);
}

async provideFeedback(messageId: string, isPositive: boolean) {
try {
await this.chatSDK.sendFeedback(messageId, 'chat_id', isPositive);
console.log('Feedback sent successfully');
} catch (error) {
console.error('Failed to send feedback:', error);
}
}
}

ナレッジベースの統合​

この例では、ナレッジ ベースにアップロードした特定のドキュメントに基づいて質問に回答できる、ナレッジ ベースを利用したチャット アプリケーションを構築する方法を説明します。 KnowledgeBasedChat クラスは、環境変数からの API 認証情報を使用して ChatSDK を初期化し、次に 2 つの主要なメソッドを使用してドキュメントを操作します。 createDocumentChat() は、documentKeys (アップロードされたドキュメントの一意の識別子) の配列を渡すことで特定のドキュメントにリンクされた新しいチャット セッションを設定し、askDocumentQuestion() はナレッジ ベース機能を有効にして AI に質問を送信します。質問するときは、useKnowledgebase: true を使用するようにチャットを構成し、AI がドキュメントから関連情報を確実に取得できるように agentType: 'document_agent' を指定します。また、formatInstructions は、出典の引用を含めるよう AI に指示します。応答には、AI が応答を生成するときにどのドキュメントを参照したかを示すソース プロパティが含まれているため、ドキュメント Q&A システム、リサーチ アシスタント、または一般的な知識ではなく特定のコンテンツに基づいた AI 応答が必要なアプリケーションの構築に最適です。これにより、AI がどのように答えに到達したかを完全に透明化できます。

import { ChatSDK } from '@odin-ai-staging/sdk';

class KnowledgeBasedChat {
private chatSDK: ChatSDK;

constructor() {
this.chatSDK = new ChatSDK({
baseUrl: process.env.API_BASE_URL,
projectId: process.env.PROJECT_ID,
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET
});
}

async createDocumentChat(documentKeys: string[], chatName?: string) {
try {
const chat = await this.chatSDK.createChat(
chatName || 'Document Q&A',
documentKeys
);

console.log(`Created document chat with ${documentKeys.length} documents`);
return chat;
} catch (error) {
console.error('Failed to create document chat:', error);
throw error;
}
}

async askDocumentQuestion(question: string, chatId: string, documentKeys?: string[]) {
try {
const response = await this.chatSDK.sendMessage(question, {
chatId,
documentKeys,
useKnowledgebase: true,
agentType: 'document_agent',
formatInstructions: 'Provide citations for your sources'
});

// Display sources if available
if (response.message.sources) {
console.log('Sources:', response.message.sources);
}

return response;
} catch (error) {
console.error('Failed to ask document question:', error);
throw error;
}
}
}

// Usage
const kbChat = new KnowledgeBasedChat();
const chat = await kbChat.createDocumentChat(['doc_1', 'doc_2'], 'Product FAQ');
const answer = await kbChat.askDocumentQuestion(
'What are the key features of the product?',
chat.chat_id
);

ベストプラクティス​

エラー処理​

すべての SDK メソッドに対して常に適切なエラー処理を実装します。

try {
const response = await chatSDK.sendMessage(message, options);
// Handle success
} catch (error) {
if (error instanceof APIError) {
// Handle API errors
console.error(`API Error: ${error.message}`);
} else {
// Handle unexpected errors
console.error('Unexpected error:', error);
}
}

ストリーミングによる UX の向上​

リアルタイムのフィードバックを提供するには、より長い応答に対してストリーミングを使用します。

// Instead of waiting for complete response
const response = await chatSDK.sendMessage(longQuery);

// Use streaming for better user experience
await chatSDK.sendMessageStream(longQuery, {
onChunk: (chunk) => updateUI(chunk),
onComplete: (message) => finalizeUI(message)
});

API 呼び出しを最適化する​

  • メッセージごとに新しいチャットを作成するのではなく、チャット ID を再利用します。
  • チャットリストにページネーションを使用する
  • 頻繁にアクセスされるデータのキャッシュを実装する
class OptimizedChatManager {
private chatCache = new Map<string, any>();
private currentChatId?: string;

async getOrCreateChat(name?: string) {
if (this.currentChatId) {
return this.currentChatId;
}

const chat = await this.chatSDK.createChat(name);
this.currentChatId = chat.chat_id;
return this.currentChatId;
}

async getCachedChatHistory(chatId: string) {
if (this.chatCache.has(chatId)) {
return this.chatCache.get(chatId);
}

const history = await this.chatSDK.getChatHistory(chatId);
this.chatCache.set(chatId, history);
return history;
}
}

構成管理​

設定を安全に保存し、環境変数を使用します。

// Good: Use environment variables
const chatSDK = new ChatSDK({
baseUrl: process.env.ODIN_API_BASE_URL,
projectId: process.env.ODIN_PROJECT_ID,
apiKey: process.env.ODIN_API_KEY,
apiSecret: process.env.ODIN_API_SECRET
});

// Bad: Hardcode credentials
const chatSDK = new ChatSDK({
baseUrl: 'https://api.example.com',
projectId: 'hardcoded-project-id',
apiKey: 'hardcoded-api-key',
apiSecret: 'hardcoded-secret'
});

メモリ管理​

リソースをクリーンアップしてメモリ リークを回避します。

class ChatApplication {
private activeStreams = new Set<AbortController>();

async sendStreamingMessage(message: string, options: any) {
const controller = new AbortController();
this.activeStreams.add(controller);

try {
await this.chatSDK.sendMessageStream(message, {
...options,
signal: controller.signal // If supported
});
} finally {
this.activeStreams.delete(controller);
}
}

cleanup() {
// Cancel all active streams
this.activeStreams.forEach(controller => controller.abort());
this.activeStreams.clear();
}
}