메인 콘텐츠로 건너뛰기
Chat API는 LLM 대화에 Neuradex의 지식을 자동으로 주입하는 Chat Completions 인터페이스입니다. OpenAI SDK 스타일의 심플한 API이면서, 프로젝트의 지식 베이스가 컨텍스트로 자동 주입됩니다. 또한, execute 함수를 가진 도구는 SDK가 자동으로 루프 실행하므로, 도구 호출 결과를 LLM에 반환하는 로직을 직접 작성할 필요가 없습니다.

개요

const client = new NdxClient({
  apiKey: process.env.NEURADEX_API_KEY,
  projectId: 'your-project-id',
});

// 텍스트 생성 (메모리 자동 주입)
const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '프로젝트 반품 정책에 대해 알려줘' }],
  memory: { enabled: true },
});

// 스트리밍으로 수신
for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);
}
메모리가 활성화되면, Neuradex는 쿼리와 관련된 지식과 에피소드를 자동으로 가져와 LLM 컨텍스트에 삽입합니다. 직접 RAG 파이프라인을 구축할 필요가 없습니다.

메서드 목록

메서드설명
create(params)Chat Completion 생성 (스트리밍 지원)

create()

Chat Completion을 생성하고 ChatStream을 반환합니다.

파라미터

model
string
필수
사용할 모델 ID (예: 'gpt-4o', 'gpt-4o-mini')
messages
ChatMessage[]
필수
메시지 배열
tools
Record<string, ChatTool>
도구 정의. execute 함수를 포함하면 SDK가 자동 실행합니다.
maxToolRoundtrips
number
기본값:"5"
도구 자동 실행 최대 라운드트립 수
memory
ChatMemoryOption
메모리 주입 옵션
temperature
number
온도 파라미터 (0~2)
maxTokens
number
최대 생성 토큰 수
stream
boolean
기본값:"true"
스트리밍 활성/비활성
onText
(text: string) => void
텍스트 청크 수신 시 콜백
onToolCall
(call) => void
도구 호출 시 콜백
onToolResult
(result) => void
도구 결과 수신 시 콜백

반환값: ChatStream

ChatStream다중 소비 패턴을 제공합니다. 동일한 스트림에서 텍스트, 이벤트, 최종 결과 중 어느 것이든 접근할 수 있습니다.
interface ChatStream {
  textStream: AsyncIterable<string>;           // 텍스트 청크 스트림
  fullStream: AsyncIterable<ChatStreamEvent>;  // 전체 이벤트 스트림
  text: Promise<string>;                       // 최종 전체 텍스트
  toolCalls: Promise<ToolCallInfo[]>;          // 모든 도구 호출 정보
  usage: Promise<ChatUsage | null>;            // 토큰 사용량
  finishReason: Promise<string>;               // 완료 사유
}

메모리 자동 주입

memory 옵션을 활성화하면, 사용자의 질문과 관련된 지식과 에피소드가 LLM 컨텍스트에 자동으로 주입됩니다.
const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '최신 반품 정책은?' }],
  memory: {
    enabled: true,
    maxTokens: 4000,         // 컨텍스트 토큰 예산
    includeEpisodes: true,   // Q&A 이력 포함
  },
});

console.log(await stream.text);

ChatMemoryOption

enabled
boolean
필수
메모리 주입 활성화 여부
maxTokens
number
주입할 컨텍스트의 최대 토큰 수
includeEpisodes
boolean
에피소드 (Q&A 이력, 변경 이력) 포함 여부

도구 자동 실행

도구 정의에 execute 함수를 포함하면, SDK가 도구 실행과 LLM으로의 결과 반환을 자동으로 처리합니다. LLM이 “도구 불필요”로 판단하거나 maxToolRoundtrips에 도달할 때까지 자동 루프합니다.
const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '도쿄 날씨를 확인하고 우산이 필요한지 알려줘' }],
  tools: {
    getWeather: {
      description: '지정한 도시의 현재 날씨를 가져옵니다',
      parameters: {
        type: 'object',
        properties: {
          city: { type: 'string', description: '도시명' },
        },
        required: ['city'],
      },
      // SDK가 이 함수를 자동 실행하고 결과를 LLM에 반환합니다
      execute: async ({ city }) => {
        const res = await fetch(`https://api.weather.example/v1/${city}`);
        const data = await res.json();
        return JSON.stringify(data);
      },
    },
  },
  maxToolRoundtrips: 3,
});

// 도구 실행을 포함한 최종 답변 가져오기
console.log(await stream.text);
execute 함수가 없는 도구가 호출되면, 스트림은 finishReason: 'tool_calls'로 종료됩니다. 이 경우 toolCalls 프로퍼티에서 호출된 도구 정보를 가져와 직접 처리할 수 있습니다.

스트리밍

textStream — 텍스트만

const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '안녕하세요!' }],
});

for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);  // 실시간 표시
}

fullStream — 전체 이벤트

도구 호출이나 완료 이벤트까지 처리하는 경우:
const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '질문' }],
  tools: { /* ... */ },
});

for await (const event of stream.fullStream) {
  switch (event.type) {
    case 'text-delta':
      process.stdout.write(event.textDelta);
      break;
    case 'tool-call':
      console.log(`도구 호출: ${event.name}`, event.args);
      break;
    case 'tool-result':
      console.log(`도구 결과: ${event.name}`, event.result);
      break;
    case 'roundtrip-complete':
      console.log(`라운드트립 ${event.roundtrip} 완료`);
      break;
    case 'finish':
      console.log(`완료: ${event.finishReason}`);
      if (event.usage) {
        console.log(`토큰: ${event.usage.totalTokens}`);
      }
      break;
    case 'error':
      console.error(`에러: ${event.error}`);
      break;
  }
}

콜백 방식

스트림을 소비하지 않고 콜백으로 처리할 수도 있습니다:
const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '질문' }],
  onText: (text) => process.stdout.write(text),
  onToolCall: (call) => console.log(`도구: ${call.name}`),
  onToolResult: (result) => console.log(`결과: ${result.result}`),
});

// 완료 대기
const finalText = await stream.text;

비스트리밍 — 최종 결과만

const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '짧게 답해줘' }],
});

// 스트림을 소비하지 않고 최종 텍스트만 가져오기
const text = await stream.text;
const usage = await stream.usage;

console.log(text);
console.log(`사용 토큰: ${usage?.totalTokens}`);

타입 정의

ChatMessage

interface ChatMessage {
  role: 'system' | 'user' | 'assistant' | 'tool';
  content: string | null;
  name?: string;
  tool_call_id?: string;
  tool_calls?: ChatToolCall[];
}

ChatTool

interface ChatTool<TArgs = Record<string, unknown>> {
  description: string;
  parameters: Record<string, unknown>;  // JSON Schema
  execute?: (args: TArgs) => Promise<string> | string;
}

ChatStreamEvent

type ChatStreamEvent =
  | { type: 'text-delta'; textDelta: string }
  | { type: 'tool-call'; toolCallId: string; name: string; args: Record<string, unknown> }
  | { type: 'tool-result'; toolCallId: string; name: string; result: string }
  | { type: 'roundtrip-complete'; roundtrip: number }
  | { type: 'finish'; usage: ChatUsage | null; finishReason: string }
  | { type: 'error'; error: string };

ChatUsage

interface ChatUsage {
  promptTokens: number;
  completionTokens: number;
  totalTokens: number;
}

유스케이스

메모리 기반 고객 지원 봇

import { NdxClient } from '@neuradex/sdk';

const client = new NdxClient({
  apiKey: process.env.NEURADEX_API_KEY,
  projectId: process.env.NEURADEX_PROJECT_ID,
});

async function handleCustomerQuery(question: string): Promise<string> {
  const stream = client.chat.create({
    model: 'gpt-4o',
    messages: [
      {
        role: 'system',
        content: '당신은 고객 지원 어시스턴트입니다. 정중하게 답변하세요.',
      },
      { role: 'user', content: question },
    ],
    memory: {
      enabled: true,
      maxTokens: 8000,
      includeEpisodes: true,  // 과거 Q&A도 참조
    },
  });

  return await stream.text;
}

도구 활용 AI 에이전트

const stream = client.chat.create({
  model: 'gpt-4o',
  messages: [
    { role: 'system', content: '당신은 일정 관리 어시스턴트입니다.' },
    { role: 'user', content: '내일 회의 리마인더 설정해줘' },
  ],
  tools: {
    createReminder: {
      description: '리마인더를 생성합니다',
      parameters: {
        type: 'object',
        properties: {
          title: { type: 'string' },
          datetime: { type: 'string', format: 'date-time' },
        },
        required: ['title', 'datetime'],
      },
      execute: async ({ title, datetime }) => {
        await db.reminders.create({ title, datetime });
        return `리마인더 "${title}"을(를) ${datetime}에 설정했습니다`;
      },
    },
    searchCalendar: {
      description: '캘린더에서 이벤트를 검색합니다',
      parameters: {
        type: 'object',
        properties: {
          query: { type: 'string' },
          date: { type: 'string', format: 'date' },
        },
        required: ['query'],
      },
      execute: async ({ query, date }) => {
        const events = await calendar.search(query, date);
        return JSON.stringify(events);
      },
    },
  },
  memory: { enabled: true },
  maxToolRoundtrips: 5,
});

for await (const event of stream.fullStream) {
  if (event.type === 'tool-call') {
    console.log(`실행 중: ${event.name}...`);
  }
  if (event.type === 'text-delta') {
    process.stdout.write(event.textDelta);
  }
}

다음 단계

React

useChat 훅으로 채팅 UI 구축

Memory API

컨텍스트 조립

Knowledge API

지식 관리