Chat SDK
O ChatSDK é o componente principal do SDK de Criação de Conteúdo do EKB que permite construir aplicativos de IA conversacional com facilidade. Ele fornece gerenciamento abrangente de chat, tratamento de mensagens, respostas por streaming e integração com base de conhecimento. Neste artigo, você aprenderá como instalar o SDK e começar rapidamente com nosso exemplo de 'Início Rápido'. Você pode explorar as diversas opções de configuração, aprender sobre autenticação e os métodos principais que podem ser usados com este SDK. Você também descobrirá exemplos de casos de uso.
Instalação
npm install @odin-ai-staging/sdk
Início Rápido
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);
}
Configuração
Interface 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
}
Opções de Configuração
- baseUrl: A URL base do seu endpoint de API
- projectId: Seu identificador único de projeto
- apiKey e apiSecret: Para autenticação do lado do servidor
- accessToken: Para autenticação do lado do cliente (aplicativos web)
Autenticação
O ChatSDK suporta dois métodos de autenticação:
Autenticação por Chave de API (Lado do Servidor)
const chatSDK = new ChatSDK({
baseUrl: 'https://api.example.com/',
projectId: 'proj_123',
apiKey: 'your-api-key',
apiSecret: 'your-api-secret'
});
Autenticação por Token de Acesso (Lado do Cliente)
const chatSDK = new ChatSDK({
baseUrl: 'https://api.example.com/',
projectId: 'proj_123',
accessToken: 'your-access-token'
});
Métodos Principais
Gerenciamento de Chat
createChat(name?, documentKeys?)
Cria uma nova conversa de chat.
async createChat(
name?: string, // Optional chat name (defaults to "Untitled")
documentKeys?: string[] // Optional document keys for knowledge base context
): Promise<CreateChatResponse>
Exemplo:
// 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?)
Recupere uma lista paginada de chats no projeto.
async listChats(
cursor?: number, // Optional cursor for pagination
limit?: number // Number of chats to return (default: 30, max: 100)
): Promise<ListChatsResponse>
Exemplo:
// 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)
Recupere um chat com seu histórico completo de mensagens.
async getChatHistory(chatId: string): Promise<ChatHistoryResponse>
Exemplo:
const chatHistory = await chatSDK.getChatHistory('chat_123');
console.log('Messages:', chatHistory.messages);
deleteChat(chatId)
Exclua um chat e todas as suas mensagens permanentemente.
async deleteChat(chatId: string): Promise<void>
Exemplo:
await chatSDK.deleteChat('chat_123');
updateChatName(chatId, newName)
Atualize o nome de exibição de um chat existente.
async updateChatName(chatId: string, newName: string): Promise<void>
Exemplo:
await chatSDK.updateChatName('chat_123', 'Updated Chat Name');
Tratamento de Mensagens
sendMessage(message, options?)
Envie uma mensagem e receba a resposta da IA.
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
}
Exemplo:
// 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)
Forneça feedback sobre uma resposta da IA.
async sendFeedback(
messageId: string,
chatId: string,
feedback: boolean // true = thumbs up, false = thumbs down
): Promise<void>
Exemplo:
// Positive feedback
await chatSDK.sendFeedback('msg_123', 'chat_123', true);
// Negative feedback
await chatSDK.sendFeedback('msg_123', 'chat_123', false);
Suporte a Streaming
sendMessageStream(message, options)
Envie uma mensagem com resposta por streaming em tempo real.
async sendMessageStream(
message: string,
options: SendMessageOptions & StreamCallbacks
): Promise<void>
StreamCallbacks:
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
}
Exemplo:
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);
}
}
);
Tratamento de Erros
O SDK lança objetos APIError para falhas relacionadas à API:
interface APIError {
message: string; // Error description
status: number; // HTTP status code
detail?: string; // Additional error details
}
Exemplo:
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);
}
}
Exemplos
Aplicativo de Chat Básico
Neste exemplo, você aprenderá como construir um aplicativo de chat básico usando o SDK do EKB com trocas de mensagens simples e sem streaming. Você começa criando uma classe SimpleChatApp que inicializa o ChatSDK com suas credenciais de API retiradas de variáveis de ambiente (URL base, ID do projeto, chave de API e secret). A classe rastreia sua sessão de chat atual com currentChatId e fornece três métodos principais: startNewChat() cria uma nova conversa de chat com um nome personalizado, sendMessage() envia uma mensagem para a IA e retorna a resposta completa (criando automaticamente um novo chat se um não existir), e getChatList() recupera todas as suas conversas de chat existentes. Ao contrário de implementações com streaming, esta abordagem aguarda a resposta completa da IA antes de exibi-la, tornando-a perfeita para casos de uso mais simples onde você não precisa de atualizações em tempo real token por token. O exemplo usa o modelo GPT-4o-mini e inclui tratamento de erros em toda parte, com registro no console para ajudá-lo a acompanhar o fluxo da conversa — fornecendo uma base direta para construir funcionalidade básica de chatbot sem a complexidade de callbacks de streaming.
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?');
Chat com Streaming e Atualizações em Tempo Real
Neste exemplo, você aprenderá como construir uma interface de chat com streaming que se conecta à API do EKB e exibe respostas da IA em tempo real. Você começa criando uma classe StreamingChat que inicializa o ChatSDK com suas credenciais de API e uma referência a um elemento HTML onde as mensagens aparecerão. Ao enviar uma mensagem usando sendStreamingMessage(), você configurará handlers de callback que processam a resposta por streaming à medida que ela chega: o callback onChunk anexa cada pedaço de texto à sua interface imediatamente (criando aquele efeito característico de "digitando"), enquanto onMessageObject permite que você lide com conteúdo rico como imagens. Você também implementará tratamento de erros com onError, atualizará o título do chat com onChatNameUpdate e usará onComplete para adicionar botões de feedback de curtir/não curtir quando a mensagem terminar de ser transmitida. Este exemplo mostra como exibir imagens dinamicamente, coletar feedback do usuário sobre respostas da IA e configurar o chat para usar o GPT-4o com integração à Base de Conhecimento — fornecendo tudo que você precisa para criar uma interface semelhante ao ChatGPT com respostas por streaming em tempo real e recursos interativos.
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);
}
}
}
Integração com Base de Conhecimento
Neste exemplo, você descobrirá como construir um aplicativo de chat alimentado por Base de Conhecimento que pode responder perguntas com base em documentos específicos que você carrega na sua Base de Conhecimento. A classe KnowledgeBasedChat inicializa o ChatSDK com suas credenciais de API de variáveis de ambiente e, em seguida, usa dois métodos-chave para interagir com seus documentos: createDocumentChat() configura uma nova sessão de chat vinculada a documentos específicos passando um array de documentKeys (identificadores únicos para seus documentos carregados), e askDocumentQuestion() envia perguntas à IA com os recursos da Base de Conhecimento habilitados. Ao fazer perguntas, você configurará o chat para usar useKnowledgebase: true e especificar agentType: 'document_agent' para garantir que a IA recupere informações relevantes dos seus documentos, enquanto formatInstructions informa à IA para incluir citações de suas fontes. A resposta inclui uma propriedade sources que mostra quais documentos a IA referenciou ao gerar sua resposta, tornando-a perfeita para construir sistemas de perguntas e respostas sobre documentos, assistentes de pesquisa ou qualquer aplicativo onde você precise de respostas da IA baseadas em conteúdo específico em vez de conhecimento geral. Isso permite transparência total sobre como a IA chegou às suas respostas.
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
);
Práticas Recomendadas
Tratamento de Erros
Sempre implemente tratamento de erros adequado para todos os métodos do 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);
}
}
Streaming para Melhor Experiência
Use streaming para respostas mais longas para fornecer feedback em tempo real:
// 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)
});
Otimize Chamadas de API
- Reutilize IDs de chat em vez de criar novos chats para cada mensagem
- Use paginação para listas de chats
- Implemente cache para dados acessados frequentemente
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;
}
}
Gerenciamento de Configuração
Armazene a configuração de forma segura e use variáveis de ambiente:
// 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'
});
Gerenciamento de Memória
Limpe recursos e evite vazamentos de memória:
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();
}
}