Chat: 인덱스 위의 내장 RAG 에이전트

Chat: 인덱스 위의 내장 RAG 에이전트

검색 API로 조각만 받는 데서 그치지 않고, 질문을 던지면 답까지 만들어 주는 채팅을 붙이고 싶을 때가 있어요. Chat API는 하나 이상의 인덱스 위에서 질문에 답하는 내장 RAG 에이전트를 제공해요. 대화 세션을 관리하고, Server-Sent Events로 응답을 스트리밍하며, 검색·도구 사용·추론까지 내부에서 알아서 처리하죠.

출처: 공식문서

세션 만들기

세션은 대화 이력을 담아요. 생성 시점에 특정 인덱스에 바인딩할 수 있는데, 첫 메시지를 보내면 바인딩된 인덱스가 세션의 수명 동안 잠겨요.

# 특정 인덱스에 바인딩된 세션
session = await client.beta.chat.create(
    index_ids=["<index-id-1>", "<index-id-2>"],
)
print(session.session_id)

# 언바인딩 세션 (인덱스는 메시지마다 지정)
session = await client.beta.chat.create()

참고로 한 세션은 최대 10개 인덱스에 바인딩할 수 있고, 매 턴마다 바인딩된 모든 인덱스로 검색이 팬아웃돼요.

메시지 스트리밍

메시지를 보내면 에이전트의 응답이 Server-Sent Events 스트림으로 돌아와요. 이 스트림에는 사고(thinking) 단계, 도구 호출(검색), 그리고 최종 텍스트 응답이 포함돼요.

이벤트를 줄 단위로 파싱하려면 각 SDK가 원시 응답 접근자를 제공해요 — Python은 with_streaming_response, TypeScript는 .asResponse(), Go는 option.WithResponseBodyInto, Java는 withRawResponse()예요.

import json

response = client.beta.chat.with_streaming_response.stream(
    session.session_id,
    index_ids=["<index-id>"],
    prompt="What are the key findings in the Q3 report?",
)

async with response as stream:
    async for line in stream.iter_lines():
        if not line or line.startswith(":"):
            continue
        if line.startswith("data: "):
            data = json.loads(line[6:])
            if data.get("type") == "text_delta":
                print(data["content"], end="", flush=True)
            elif data.get("type") == "stop":
                print("\n--- Done ---")
            else:
                print(data)  # handle other event types as needed

CLI(llp beta:chat stream)는 예외로, 한 턴 전체를 버퍼링하고 에이전트가 끝나면 누적된 이벤트 페이로드를 출력해요. 턴을 점검하는 데는 유용하지만 실시간 자바스크립트 델타 렌더링에는 안 맞아요.

이벤트 타입

스트림은 두 종류의 이벤트를 내보내요.

델타 이벤트 (event: delta) — 실시간 표시용 증분 콘텐츠:

타입 설명
text_delta 에이전트 응답 텍스트의 일부.
thinking_delta 에이전트 추론의 일부 (노출된 경우).

메시지 이벤트 (event: message) — 완결된 개별 이벤트:

타입 설명
text 완전한 에이전트 응답 텍스트.
thinking 완전한 에이전트 추론 블록.
user_input 사용자의 원래 메시지.
tool_call 에이전트의 도구 호출 (예: 검색).
tool_result 도구 호출의 결과.
stop 스트림 종료, 토큰 사용량 포함.
warning 정보성 경고 (예: 건너뛴 인덱스).

세션 목록·상세·삭제

세션은 목록으로 조회하고, 요약만 또는 전체 이벤트 이력으로 상세를 열어볼 수 있어요.

# 목록
sessions = await client.beta.chat.list()
for s in sessions.items:
    print(f"{s.session_id}: {s.generated_title or '(untitled)'}")

# 요약만
summary = await client.beta.chat.get_summary(session.session_id)
print(summary.generated_title)

# 전체 세션 (이벤트 이력 포함)
full = await client.beta.chat.retrieve(session.session_id)
for event in full.events:
    print(event.type, event.content[:100] if hasattr(event, "content") else "")

# 삭제
await client.beta.chat.delete(session.session_id)

더 알아보기