매 호출은 독립적.
챗봇이 어제를 기억하는 것처럼 보이는 건,
client가 매번 history를 통째로 다시 보내고 있기 때문.
매 턴이 끝날 때마다
user 메시지 1개 + assistant 메시지 1개를 append.
다음 호출 때 list를 messages에 통째로 끼워 보낸다.
history = [
{"role": "user",
"content": "이력서 평가해줘 ..."},
{"role": "assistant",
"content": "공고가 없어 평가가 ..."},
{"role": "user",
"content": "공고 줄게 ..."},
{"role": "assistant",
"content": "평가 결과는 ..."},
# ... 계속 append
]
def generate_response_with_history(user_prompt, history): messages = [{"role": "system", "content": system_prompt}] messages.extend(history) # 과거 대화 messages.extend([{"role": "user", "content": user_prompt}]) # 이번 턴 response = client.chat.completions.create( model=os.getenv("model"), messages=messages, stream=True, ) return "".join(c.choices[0].delta.content for c in response if c.choices) history = [] # 시작은 빈 리스트
변한 건 messages 조립 부분뿐. system + history(N) + 이번 user 순서.
# 1턴 user_prompt_1 = f"이력서 평가해줘 [이력서]{resume}" response_1 = generate_response_with_history(user_prompt_1, history) history.append({"role": "user", "content": user_prompt_1}) history.append({"role": "assistant", "content": response_1}) # 2턴 — history엔 이미 1턴 내용이 들어 있음 user_prompt_2 = f"공고로 평가 [공고]{jp}" response_2 = generate_response_with_history(user_prompt_2, history) history.append({"role": "user", "content": user_prompt_2}) history.append({"role": "assistant", "content": response_2})
user/assistant 짝을 맞춰 append. assistant 응답을 빼먹으면 LLM이 자기 답을 못 본다.
대화가 길어지면 매 호출 비용·지연도 같이 늘어난다.
후반 챕터의 패턴: summarize · trim · 컨텍스트 윈도우 관리.
기억하는 LLM = 챗봇. 하지만 DB 조회, 파일 저장, 메일 발송은 여전히 못 한다.