AI

Chats

Vector 동기화된 콘텐츠와 Agent를 이용해 RAG 기반 채팅을 제공하는 Chats API 사용 방법을 설명합니다.

Chats

Chats API는 Vector 동기화된 콘텐츠를 시맨틱 검색으로 찾아 Agent가 답변을 생성하는 RAG(Retrieval-Augmented Generation) 채팅 API입니다. 이 가이드를 완료하면 채팅 세션을 생성하고, 메시지를 주고받고, 대화 이력을 조회할 수 있습니다.

사전 조건:

  • 검색 대상 Table의 Vector 동기화가 완료되어 있어야 합니다.
  • Agent가 생성되어 있어야 합니다.
  • 읽기 권한이 있는 Project API Key가 필요합니다.

동작 방식

  1. 요청의 message를 임베딩해 Vector 동기화된 콘텐츠에서 관련 Contents를 검색합니다. threshold 이상의 유사도를 가진 항목을 최대 count개까지 사용합니다.
  2. 검색된 콘텐츠와 대화 이력을 컨텍스트로 구성합니다.
  3. agent_id로 지정한 Agent의 모델과 Instructions에 따라 답변을 스트리밍으로 생성합니다.

tableIds를 지정하면 특정 Table로 검색 범위를 제한할 수 있습니다. 생략하면 Project의 모든 Table을 검색합니다.


1. 새 채팅 세션 시작

POST /v1/{projectId}/chats

요청 본문

필드 타입 필수 기본값 설명
agent_id string 필수 - 사용할 Agent의 ID. Agents 페이지에서 확인합니다
message string 필수 - 사용자 메시지 (1자 이상)
threshold number - 0.7 검색 결과에 포함할 최소 유사도 점수 (0–1)
count integer - 5 컨텍스트에 포함할 관련 콘텐츠 최대 개수 (1–100)
tableIds string[] - - 검색 범위를 제한할 Table ID 목록. 생략하면 모든 Table을 검색
is_plain boolean - false true이면 Markdown 없이 일반 텍스트로 답변하도록 지시

요청 예제

curl -X POST "https://api.onttle.com/v1/{projectId}/chats" \
  -H "Authorization: Bearer $ONTTLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "Ag3ntId_ExAmPle123",
    "message": "환불 정책이 어떻게 되나요?"
  }'

응답

응답은 text/plain 스트리밍으로 전달되며, 전체를 이어 붙이면 하나의 JSON 객체가 됩니다.

{
  "chatId": "chat_xyz789",
  "message": "환불 정책은 구매 후 30일 이내 반품을 허용합니다...",
  "contents": [{ "id": "cont_abc", "table_id": "tbl_abc123" }]
}

chatId는 이후 메시지 전송과 대화 이력 조회에 사용합니다. contents는 답변에 참조된 콘텐츠 목록으로, 출처 표시에 활용할 수 있습니다.


2. 기존 세션에 메시지 전송

POST /v1/{projectId}/chats/{chatId}/messages

요청 본문은 새 채팅 세션 시작과 동일합니다. 서버가 기존 대화 이력을 함께 구성해 문맥을 유지한 답변을 생성합니다.

요청 예제

curl -X POST "https://api.onttle.com/v1/{projectId}/chats/{chatId}/messages" \
  -H "Authorization: Bearer $ONTTLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "Ag3ntId_ExAmPle123",
    "message": "30일이 지나면 환불이 안 되나요?"
  }'

응답 (스트리밍, 조립 후)

{
  "chatMessageId": "msg_ai002",
  "message": "30일이 지난 경우 제품 하자가 아니라면 환불이 어렵습니다...",
  "contents": [{ "id": "cont_abc", "table_id": "tbl_abc123" }]
}

3. 대화 이력 조회

GET /v1/{projectId}/chats/{chatId}/messages

세션의 메시지를 생성 순서(오래된 순)로 최대 20개까지 반환합니다.

Query 파라미터 타입 필수 설명
lastId string - 마지막으로 받은 메시지 ID. 지정하면 이후에 생성된 메시지만 반환합니다

요청 예제

curl "https://api.onttle.com/v1/{projectId}/chats/{chatId}/messages?lastId=msg_ai001" \
  -H "Authorization: Bearer $ONTTLE_API_KEY"

응답 예시

{
  "data": [
    {
      "id": "msg_user001",
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z",
      "agent_id": null,
      "message": "환불 정책이 어떻게 되나요?",
      "chat_messages_contents_connections": []
    },
    {
      "id": "msg_ai001",
      "created_at": "2026-01-01T00:00:02.000Z",
      "updated_at": "2026-01-01T00:00:05.000Z",
      "agent_id": "Ag3ntId_ExAmPle123",
      "message": "환불 정책은 구매 후 30일 이내 반품을 허용합니다...",
      "chat_messages_contents_connections": [
        {
          "id": "conn_001",
          "order": 1,
          "score": 0.92,
          "contents": {
            "id": "cont_abc",
            "title": "환불 정책",
            "data": { "body": "구매 후 30일 이내 반품 가능..." },
            "slug": "refund-policy",
            "icon": "📄",
            "table_id": "tbl_abc123"
          }
        }
      ]
    }
  ]
}

agent_id가 null이면 사용자 메시지, 값이 있으면 AI 답변입니다. chat_messages_contents_connections에는 답변에 참조된 콘텐츠와 유사도 점수(score)가 포함됩니다.


TypeScript 스트리밍 예제

const res = await fetch('https://api.onttle.com/v1/{projectId}/chats', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ONTTLE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    agent_id: 'Ag3ntId_ExAmPle123',
    message: '환불 정책이 어떻게 되나요?',
  }),
})

const reader = res.body!.getReader()
const decoder = new TextDecoder()
let raw = ''

while (true) {
  const { done, value } = await reader.read()
  if (done) break
  raw += decoder.decode(value, { stream: true })
}

const { chatId, message, contents } = JSON.parse(raw)
// chatId: 이후 메시지 전송에 사용
// message: AI 답변
// contents: 참조된 콘텐츠 목록

문제 해결

증상 확인 사항
콘텐츠와 무관한 답변 대상 Table의 Vector 동기화 상태가 SUCCESS인지 확인, threshold를 높여 정확도 개선
참조 콘텐츠가 비어 있음 threshold를 낮추거나 count를 늘려 검색 범위 확대, tableIds 지정 여부 확인
agent_id 오류 Agents 페이지에서 Agent ID를 다시 확인

다음 단계

  • Agents — 답변 스타일과 모델을 조정합니다.
  • Vector — 검색 대상 콘텐츠를 동기화합니다.
  • Embeddings 검색 — 채팅 없이 시맨틱 검색만 사용합니다.