챗 API로 대화형 앱 만들기

챗 API로 대화형 앱 만들기

파운데이션 모델을 그냥 text/generation으로 부르는 대신, 대화 맥락을 유지하며 주고받고 싶을 때는 챗 API가 훨씬 자연스러워요. watsonx.ai의 챗 API는 시스템 프롬프트, 사용자 입력, 모델 응답 같은 메시지 타입을 구분해 대화형 워크플로를 만들 수 있게 해줘요.

출처: Adding generative chat function to your applications with the chat API - IBM watsonx.ai 공식 문서

권한과 자격 증명

프롬프트를 실행하려면 프로젝트에서 Admin 또는 Editor 역할이 필요해요. watsonx.ai API 인증을 위한 자격 증명(베어러 토큰)도 미리 준비해야 해요.

개발 방법

챗 워크플로는 REST API, Python, Node.js, LangChain (Python/JS)으로 만들 수 있어요. GUI를 좋아한다면 watsonx.ai UI에서 문서·미디어 파일과 채팅하는 기능을 쓸 수도 있어요.

챗 API 개요

챗 API는 파운데이션 모델과 대화형으로 상호작용하는 메서드를 제공해요. 시스템 프롬프트, 사용자 입력, 모델 출력 같은 메시지 타입을 구분할 수 있고, 사용자별 후속 질문과 답변까지 다룰 수 있어요. Prompt Lab의 챗 모드에서 모델과 대화하며 얻는 흐름을 그대로 API로 흉내 낸다고 보면 돼요.

어떤 모델이 챗을 지원하나

챗 API를 지원하는 파운데이션 모델 목록은 List the available foundation models 메서드에 filters=function_text_chat 파라미터를 넣으면 받아올 수 있어요.

curl -X GET \
 'https://<region>.<cloud-provider-domain>/ml/v1/foundation_model_specs?version=2024-10-10&filters=function_text_chat'

도구 호출을 지원하는 모델로 에이전트형 워크플로를 만들려면 "Building agent-driven workflows with the chat API" 문서를 참고해요. 커스텀 파운데이션 모델로도 챗 워크플로를 만들 수 있어요.

REST API로 챗 요청 보내기

챗 API로 할 수 있는 작업은 크게 세 가지예요.

  • 여러 사용자와 대화하기
  • 추론(reasoning) 능력이 있는 모델과 대화하기
  • 이미지에 대해 모델과 대화하기

다중 사용자 대화의 예시를 볼게요. 요청에는 model_id, project_id, 그리고 messages 배열에 대화 내용을 넣으면 돼요.

curl --request POST 'https://<region>.<cloud-provider-domain>/ml/v1/text/chat?version=2024-10-08'
-H 'Authorization: Bearer ***'
-H 'Content-Type: application/json'
-H 'Accept: application/json'
-d '{
 "model_id": "meta-llama/llama-3-8b-instruct",
 "project_id": "<project ID>",
 "messages": [
 {
 "role": "system",
 "content": "You are a helpful assistant that avoids causing harm. When you do not know the answer to a question, you say 'I do not know'."
 },
 {
 "role": "user",
 "content": [
 {
 "type": "text",
 "text": "I have a question about Earth. How many moons does the Earth have?"
 }
 ]
 },
 {
 "role": "assistant",
 "content": "The Earth has one natural satellite, which is simply called the Moon."
 },
 {
 "role": "user",
 "content": [
 {
 "type": "text",
 "text": "What about Saturn?"
 }
 ]
 }
 ],
 "max_tokens": 300,
 "time_limit": 1000
}'

응답은 OpenAI 스타일과 비슷하게 choices, usage(토큰 수), created_at 등을 담고 있어요. 이 예시 응답에서는 모델이 Saturn has a total of 82 confirmed moons!라고 답했어요.

⚠️ 챗 세션 메시지의 role 파라미터는 대소문자를 구분해요. 반드시 소문자로 설정하세요.

추론 능력이 있는 모델과 대화하기

일부 파운데이션 모델은 응답과 함께 상세한 추론 정보를 제공해요. chat_template_kwargs.thinking으로 reasoning을 켜고, reasoning_effort로 세부 수준을 조절할 수 있어요. include_reasoning: true를 주면 응답에 reasoning_content가 함께 오는 걸 볼 수 있죠.

curl -X POST -kLsS 'https://<region>.<cloud-provider-domain>/ml/v1/text/chat?version=2025-10-25' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ***" \
-d '{
 "stream": false,
 "model_id": "openai/gpt-oss-120b",
 "project_id": "<project ID>",
 "messages": [
 {
 "role": "user",
 "content": "Hi there. What weighs more, a pound of feathers or a kilogram of lead?"
 }
 ],
 "chat_template_kwargs": {
 "thinking": true
 },
 "reasoning_effort": "high",
 "include_reasoning": true,
 "max_completion_tokens": 5000
}'

이 예시 응답에서 모델은 "킬로그램의 납이 더 무겁다"는 결론과 함께, 단위 환산과 부피 비교까지 reasoning_content에 담아 상세하게 설명했어요.

이미지에 대해 대화하기

챗 API로 이미지를 설명하게 하려면 이미지를 Base64로 인코딩해 메시지에 넣으면 돼요. 이미지 요구 사항은 이래요.

  • 챗 하나당 이미지 1개
  • 지원 파일 형식은 PNG 또는 JPEG
  • 이미지 크기에 따라 한 장당 약 1,200~3,000 토큰으로 계산돼요

파이썬에서 이미지를 Base64로 인코딩하는 코드는 다음과 같아요.

import wget, os, base64
filename = 'downloaded-image.png'
url = 'https://www.ibm.com/able/static/my-input-image.png'
if not os.path.isfile(filename):
 wget.download(url, out=filename)
with open(filename, 'rb') as image_file:
 image_b64_encoded_string = base64.b64encode(image_file.read()).decode('utf-8')

인코딩한 문자열은 메시지의 image_url.url 값으로 지정하면 돼요. 요청에는 비전(vision) 모델을 쓰는 걸 잊지 마세요.

curl --request POST 'https://<region>.<cloud-provider-domain>/ml/v1/text/chat?version=2024-10-09'
-H 'Authorization: Bearer ***'
-H 'Content-Type: application/json'
-H 'Accept: application/json'
-d '{
 "model_id": "meta-llama/llama-3-2-11b-vision-instruct",
 "project_id": "<project ID>",
 "messages": [
 {
 "role": "user",
 "content": [
 {
 "type": "image_url",
 "image_url": {
 "url": "<encoded_string>"
 }
 },
 {
 "type": "text",
 "text": "What does the image convey about alternative image text?"
 }
 ]
 }
 ],
 "max_tokens": 300,
 "time_limit": 10000
}'

이 예시 응답에서 모델은 "노트북 화면의 막대그래프와 그 대체 텍스트"를 정확히 설명해 줬어요. 접근성 관점에서 이미지에 대한 대체 텍스트가 왜 중요한지도 함께 짚어 줬죠.

파이썬에서 쓰기

파이썬에서는 watsonx.ai 라이브러리의 ModelInference 클래스를 사용해요. 대화형 작업, 이미지 챗, JSON 응답 형식 챗을 다루는 예제 노트북이 준비돼 있으니 그걸 시작점으로 삼으면 돼요.

챗 API 문제 해결

응답이 HTML 형식이면서 Gateway time-out 문구가 나온다면, 요청이 너무 오래 걸려 만료된 거예요. 요청의 time_limit 필드 값을 늘려 보세요.

더 알아보기