AI 관련 책이나 예제 코드를 보면 같은 OpenAI를 쓰는데도 코드 스타일이 서로 다릅니다.
최근 제가 샀던 책에서도 기본적인 샘플 코드임에도 약간씩 차이가 나는 부분이 있어서 개념을 이해하는데 더 어렵게 느껴지는 부분도 있었습니다.
어떤 책은 prompt를 쓰고,
어떤 책은 messages를 쓰고,
최근 문서는 responses.create()를 씁니다.
여기에 LangChain까지 들어오면 더 헷갈립니다.
이 글에서는 OpenAI API의 흐름을 다음 기준으로 정리합니다.
Completion → Chat Completions → Responses → LangChain에서 Responses 붙이는 방법
1. 한 줄 요약
| 구분 | 핵심 개념 |
|---|---|
| Completion | prompt 기반 텍스트 생성 |
| Chat Completions | messages 기반 대화 생성 |
| Responses | 텍스트, 툴 호출, 멀티모달, 구조화 출력을 하나의 응답 객체로 통합 |
| LangChain | 내부는 Chat 인터페이스를 유지하면서 Responses API를 선택적으로 사용 |
👉 핵심:
Responses = Chat의 확장판 (상위 개념)
2. 왜 API가 바뀌었을까?
예전에는 단순히 텍스트 생성만 잘하면 됐습니다.
하지만 지금은 다음이 필요합니다:
- 함수 호출 (Tool Calling)
- JSON 구조화 응답
- 이미지/오디오 처리
- 검색 / 코드 실행
- 멀티모달
👉 기존 구조로는 한계 발생. 그래서 나온 것이:
Responses API (통합 작업 인터페이스)
3. Completion (구형 방식)
const r = await client.completions.create({
model: "text-davinci-003",
prompt: "AI를 한 문장으로 설명해줘"
});
console.log(r.choices[0].text);구조:
입력: prompt
출력: text❗ 문제:
- 대화 관리 불편
- 구조화 어려움
4. Chat Completions (대화 중심)
const r = await client.chat.completions.create({
model: "gpt-4.1-mini",
messages: [
{ role: "system", content: "친절한 설명가" },
{ role: "user", content: "AI가 뭐야?" }
]
});
console.log(r.choices[0].message.content);구조:
입력: messages[]
출력: message.content장점:
- 역할 분리
- 대화 구조 자연스러움
5. Responses API (현재 핵심)
Responses는 단순 텍스트가 아닙니다.
response.output = [
{
type: "message",
content: [{ type: "output_text", text: "답변입니다." }]
},
{
type: "tool_call",
name: "getWeather",
arguments: "{ \"city\": \"Seoul\" }"
}
];👉 핵심:
응답 = 여러 output 아이템의 배열
텍스트 추출:
const text = r.output
.flatMap(item => item.content ?? [])
.filter(c => c.type === "output_text")
.map(c => c.text)
.join("");6. 구조 비교
- 항목 Completion Chat Responses
- 입력 prompt messages input
- 출력 text message output[]
- 개념 생성 대화 작업
7. 툴 호출 방식 변화
1) Chat 방식
message.tool_calls
2) Responses 방식
output: [{ type: "tool_call" }]
👉 변화:
메시지 내부 → 독립된 이벤트 구조
8. LangChain에서는 어떻게 보일까?
LangChain은 OpenAI API를 감싸는 라이브러리입니다.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4.1-mini")
result = llm.invoke("AI 설명해줘")
print(result.content)👉 여기서 중요한 오해:
ChatOpenAI = Chat API ❌
ChatOpenAI = LangChain 인터페이스 ✅
9. LangChain에서 Responses API 붙이기
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4.1-mini",
use_responses_api=True,
output_version="responses/v1",
)옵션 설명:
| 옵션 | 의미 |
|---|---|
| use_responses_api | Responses API 사용 |
| output_version | 출력 구조를 LangChain에 맞게 변환 |
10. 텍스트 응답 처리
response = llm.invoke("설명해줘")
print(response.content)⚠️ 주의:
response.content는 항상 문자열이 아닐 수 있음
안전한 처리:
for block in response.content:
if isinstance(block, dict) and block.get("type") == "text":
print(block["text"])11. 구조화 출력 (JSON 대신 스키마)
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
structured_llm = llm.with_structured_output(Person)
result = structured_llm.invoke("철수는 12살")
print(result)👉 결과:
Person(name="철수", age=12)
12. Tool Calling
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
return f"{city}의 날씨는 맑음"
llm_with_tools = llm.bind_tools([get_weather])
response = llm_with_tools.invoke("서울 날씨 알려줘")👉 내부 흐름:
모델 → tool 호출 → 함수 실행 → 결과 반환 → 최종 답변
13. Agent 흐름
User
↓
Model
↓
Tool Call
↓
Function 실행
↓
Tool Result
↓
Model
↓
Final Answer
14. LangChain vs Responses 관계
OpenAI Responses API
↓
LangChain ChatOpenAI
↓
AIMessage / tool_calls / content_blocks
👉 LangChain은 Responses 구조를 감싸서 사용
15. 언제 무엇을 써야 하나?
| 상황 | 추천 |
|---|---|
| 간단 챗봇 | Chat |
| JSON 응답 | Responses |
| Tool 사용 | Responses |
| Agent | Responses |
| 멀티모달 | Responses |
👉 한 줄:
조금이라도 복잡하면 Responses
16. 마이그레이션 체크리스트
output을 문자열 하나로 가정하지 않았는가?
→output_text만 보지 말고,output배열 구조를 함께 확인JSON을 문자열로 파싱하고 있지 않은가?
→ 이미 구조화된 응답이면 문자열JSON.parse()전제는 제거tool 호출 흐름을 처리했는가?
→function_call/tool관련 출력이 나오면 후속 실행 루프 필요Responses 구조를 이해했는가?
→ Chat Completions 방식이 아니라response.output중심으로 처리LangChain에서
use_responses_api설정했는가?
→ LangChain OpenAI 래퍼 사용 시 해당 옵션 활성화 여부 확인
17. 핵심 개념 정리
- Completion = 텍스트 생성
- Chat = 대화
- Responses = 작업 실행
18. 결론
OpenAI API는 이렇게 진화했습니다:
텍스트 생성 → 대화 → 작업 실행
👉 가장 중요한 한 줄:
Chat은 대화 인터페이스이고,
Responses는 작업 인터페이스다

0 댓글