Episodes API는 에피소드(이벤트)를 시간순으로 기록하고 조회하기 위한 인터페이스입니다. Q&A 이력, 지식 변경 이력, 사용자 액션 등을 추적할 수 있습니다.
const client = new NdxClient({
apiKey: process.env.NEURADEX_API_KEY,
projectId: 'your-project-id',
});
// Episodes API 접근
const episodes = await client.episodes.list({ timeRange: 'today' });
await client.episodes.create({ ... });
메서드 목록
| 메서드 | 설명 |
|---|
list(options?) | 에피소드 목록 조회 |
get(id) | 특정 에피소드 조회 |
create(input) | 새 에피소드 기록 |
getChildren(id) | 자식 에피소드 조회 |
getBySession(sessionId) | 세션 내 에피소드 조회 |
getRecent(limit?) | 최근 에피소드 조회 |
getToday() | 오늘 에피소드 조회 |
getThisWeek() | 이번 주 에피소드 조회 |
search(query, options?) | 에피소드 벡터 검색 |
list()
조건을 지정하여 에피소드 목록을 조회합니다.
파라미터
시간 범위 프리셋: 'today' | 'this_week' | 'this_month'
에피소드 타입 필터: 'question' | 'answer' | 'knowledge_created' 등
액터 타입 필터: 'user' | 'agent' | 'system'
채널 필터: 'widget' | 'api' | 'mcp'
반환값
interface EpisodeListResponse {
data: Episode[];
total: number;
page: number;
limit: number;
}
interface Episode {
id: string;
episodeType: string;
content: string;
actorType: string;
actorId: string | null;
actorName: string | null;
scopeType: string;
scopeId: string;
channel: string | null;
sessionId: string | null;
parentEpisodeId: string | null;
relatedKnowledgeIds: string[];
changeReason: string | null;
previousValue: object | null;
occurredAt: string;
createdAt: string;
}
사용 예
// 오늘 에피소드
const result = await client.episodes.list({ timeRange: 'today' });
// 특정 사용자의 에피소드
const result = await client.episodes.list({
actorType: 'user',
actorId: 'user-123',
limit: 100,
});
// 날짜 범위로 조회
const result = await client.episodes.list({
from: '2025-01-01T00:00:00Z',
to: '2025-01-07T23:59:59Z',
});
// 질문 에피소드만
const result = await client.episodes.list({
episodeType: 'question',
});
get()
특정 에피소드를 조회합니다.
파라미터
사용 예
const episode = await client.episodes.get('episode-123');
console.log(episode.content);
console.log(episode.actorName);
console.log(episode.occurredAt);
create()
새 에피소드를 기록합니다.
파라미터
액터 타입: 'user' | 'agent' | 'system'
에피소드 타입: 'question' | 'answer' | 'feedback' 등
스코프 타입: 'project' | 'organization'
스코프 ID (프로젝트 ID 또는 조직 ID)
채널: 'widget' | 'api' | 'mcp'
부모 에피소드 ID (답변을 질문에 연결 등)
사용 예
// 사용자 질문 기록
const question = await client.episodes.create({
actorType: 'user',
actorId: 'user-123',
actorName: 'John Doe',
episodeType: 'question',
content: '비밀번호를 재설정하려면 어떻게 하나요?',
scopeType: 'project',
scopeId: 'project-abc',
channel: 'widget',
sessionId: 'session-xyz',
});
// 에이전트 답변 기록
const answer = await client.episodes.create({
actorType: 'agent',
actorName: 'Support Bot',
episodeType: 'answer',
content: '로그인 화면의 "비밀번호 찾기" 링크를 클릭하여 비밀번호를 재설정할 수 있습니다.',
scopeType: 'project',
scopeId: 'project-abc',
channel: 'widget',
sessionId: 'session-xyz',
parentEpisodeId: question.id, // 질문에 연결
relatedKnowledgeIds: ['knowledge-1', 'knowledge-2'],
});
getChildren()
지정된 에피소드의 자식 에피소드(답변 등)를 조회합니다.
파라미터
사용 예
// 질문에 대한 답변 조회
const children = await client.episodes.getChildren('question-episode-id');
for (const child of children) {
console.log(`답변: ${child.content}`);
}
getBySession()
세션 내 모든 에피소드를 조회합니다. 대화 이력 조회에 유용합니다.
파라미터
사용 예
// 대화 이력 조회
const result = await client.episodes.getBySession('session-123');
for (const episode of result.data) {
const prefix = episode.episodeType === 'question' ? 'Q' : 'A';
console.log(`${prefix}: ${episode.content}`);
}
getRecent()
최근 에피소드를 조회합니다.
파라미터
사용 예
// 최근 10건
const result = await client.episodes.getRecent();
// 최근 50건
const result = await client.episodes.getRecent(50);
getToday() / getThisWeek()
오늘/이번 주 에피소드를 조회하는 단축 메서드입니다.
사용 예
// 오늘 에피소드
const today = await client.episodes.getToday();
// 이번 주 에피소드
const thisWeek = await client.episodes.getThisWeek();
search()
벡터 검색으로 에피소드를 검색합니다. “비밀번호 재설정”, “지난주 에러” 등 모호한 쿼리로도 관련 에피소드를 찾을 수 있습니다.
파라미터
반환값
interface EpisodeSearchResponse {
results: EpisodeSearchResult[];
query: string;
}
interface EpisodeSearchResult {
id: string;
episodeType: string;
content: string;
actorType: string;
actorName: string | null;
occurredAt: string;
channel: string | null;
score: number;
}
사용 예
// 에피소드 검색
const result = await client.episodes.search('비밀번호 재설정');
for (const episode of result.results) {
console.log(`${episode.actorName}: ${episode.content} (점수: ${episode.score})`);
}
// 건수 지정
const result = await client.episodes.search('배포 에러', { limit: 5 });
에피소드 타입
| 타입 | 설명 |
|---|
question | 사용자 질문 |
answer | 에이전트 답변 |
feedback | 사용자 피드백 |
knowledge_created | 지식 생성 |
knowledge_updated | 지식 수정 |
knowledge_deleted | 지식 삭제 |
search | 검색 실행 |
유스케이스
대화 이력 저장
async function recordConversation(
sessionId: string,
question: string,
answer: string,
userId: string,
) {
// 질문 기록
const questionEpisode = await client.episodes.create({
actorType: 'user',
actorId: userId,
episodeType: 'question',
content: question,
scopeType: 'project',
scopeId: projectId,
channel: 'api',
sessionId,
});
// 답변 기록
await client.episodes.create({
actorType: 'agent',
actorName: 'Assistant',
episodeType: 'answer',
content: answer,
scopeType: 'project',
scopeId: projectId,
channel: 'api',
sessionId,
parentEpisodeId: questionEpisode.id,
});
}
활동 대시보드
async function getActivityStats() {
const today = await client.episodes.getToday();
const stats = {
questions: today.data.filter(e => e.episodeType === 'question').length,
answers: today.data.filter(e => e.episodeType === 'answer').length,
uniqueUsers: new Set(
today.data
.filter(e => e.actorType === 'user')
.map(e => e.actorId)
).size,
};
console.log(`오늘 질문 수: ${stats.questions}`);
console.log(`오늘 답변 수: ${stats.answers}`);
console.log(`유니크 사용자: ${stats.uniqueUsers}`);
return stats;
}
다음 단계