포스트

2026-03-27 강의 정리

대화 이력 관리를 위한 메모리 구현 (Chat History)

2026-03-27 강의 정리

목차

  1. 왜 메모리가 필요한가?
  2. 수동으로 대화 기록 관리하기
  3. 토큰 카운팅 (tiktoken)
  4. ConversationBufferMemory (langchain_classic)
  5. InMemoryChatMessageHistory (langchain_core)
  6. RunnableWithMessageHistory — 세션 기반 자동 관리
  7. Window Memory — 최근 N개 턴만 유지
  8. Summary Memory — 오래된 대화 요약으로 압축
  9. SummaryChatbot — 요약 메모리 통합 챗봇
  10. 자주 나오는 실수 / 주의사항
  11. [보충] 메모리 전략 비교

1. 왜 메모리가 필요한가?

LLM(대규모 언어 모델)은 기본적으로 무상태(stateless) 입니다. 각 invoke() 호출은 완전히 독립된 요청이므로, 이전 대화 내용을 전혀 기억하지 못합니다.

1
2
3
4
5
llm.invoke('내 이름은 abc입니다.').content
# → '안녕하세요, abc님! 어떻게 도와드릴까요?'

llm.invoke('내 이름은 뭔가요?').content
# → '죄송하지만, 당신의 이름은 알 수 없습니다...'

▶ 문제: 두 번째 호출 때는 첫 번째 호출의 정보가 없기 때문에 이름을 모릅니다.

해결책: 대화 기록을 직접 전달

messages 리스트에 대화 히스토리를 누적해서 LLM에 함께 전달해야 합니다.

1
2
3
4
5
6
7
[SystemMessage] 당신은 친절한 AI 어시스턴트입니다
    ↓
[HumanMessage] 내 이름은 abc입니다
    ↓
[AIMessage] 반가워요, abc님!
    ↓
[HumanMessage] 내 이름은 뭔가요?    ← 이 시점에 위의 히스토리가 함께 전달됨

메모리 전략 3가지

1
2
3
4
5
6
7
┌─────────────────────────────────────────────────────┐
│  메모리 전략                                          │
│                                                     │
│  1. Buffer     : 모든 대화 저장 (무제한)              │
│  2. Window     : 최근 K개 턴만 유지 (슬라이딩 윈도우)  │
│  3. Summarize  : 오래된 대화를 요약으로 압축           │
└─────────────────────────────────────────────────────┘

2. 수동으로 대화 기록 관리하기

messages 리스트에 SystemMessage / HumanMessage / AIMessage를 순서대로 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage

messages = [
    SystemMessage(content='당신은 친절한 AI 어시스턴트입니다'),
    HumanMessage(content='내 이름은 abc입니다. 반가워요')
]

response1 = llm.invoke(messages)
print(response1.content)
# → 반가워요, abc님! 어떻게 도와드릴까요?

# AI 응답을 기록에 추가하고, 다음 질문도 추가
messages.append(AIMessage(content=response1.content))
messages.append(HumanMessage(content='내 이름은 뭔가요?'))

response2 = llm.invoke(messages)
print(response2.content)
# → 당신의 이름은 abc입니다! 다른 질문이 있으신가요?

▶ 포인트: AIMessage를 직접 messages에 추가해야 다음 턴에서 이전 맥락을 기억합니다.


3. 토큰 카운팅 (tiktoken)

대화가 길어질수록 토큰 수가 증가해 비용과 속도에 영향을 줍니다. tiktoken으로 현재 대화의 토큰 수를 측정할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
import tiktoken

enc = tiktoken.encoding_for_model('gpt-4o-mini')

def count_tokens(messages):
    total = 0
    for msg in messages:
        total += len(enc.encode(msg.content))
        total += 4  # 메시지 구분자 토큰 (OpenAI 규격)
    return total

실제 측정 예시:

턴 수누적 토큰
1턴 (교환 1회)50
2턴 (교환 2회)82

▶ 주의: 대화가 쌓일수록 토큰이 선형 증가합니다. 100턴이면 수천 토큰 → 메모리 전략 필수.


4. ConversationBufferMemory (langchain_classic)

Deprecated 경고 발생 (현재는 langchain_coreInMemoryChatMessageHistory 권장)

기본 사용법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from langchain_classic.memory import ConversationBufferMemory

memory = ConversationBufferMemory(return_messages=True)  # True: 메시지 객체 반환

memory.save_context(
    {'input': '안녕하세요, 저는 abc입니다'},
    {'output': '안녕하세요, abc님! 만나서 반갑습니다'}
)
memory.save_context(
    {'input': '오늘 날씨가 좋네요!'},
    {'output': '네, 정말 화창한 날씨입니다'}
)

history = memory.load_memory_variables({})

return_messages 옵션 차이

return_messages반환 형식
True[HumanMessage(...), AIMessage(...), ...] — 메시지 객체 리스트
False'Human: ...\nAI: ...' — 하나의 문자열
1
2
3
4
5
6
7
8
9
10
# return_messages=True 결과
{'history': [
    HumanMessage(content='안녕하세요, 저는 abc입니다'),
    AIMessage(content='안녕하세요, abc님! 만나서 반갑습니다'),
    HumanMessage(content='오늘 날씨가 좋네요!'),
    AIMessage(content='네, 정말 화창한 날씨입니다')
]}

# return_messages=False 결과
{'history': 'Human: 안녕하세요, 저는 abc입니다\nAI: 안녕하세요, abc님! 만나서 반갑습니다\n...'}

▶ 실무 팁: 체인(Chain)에 주입할 때는 return_messages=True(메시지 리스트)가 더 범용적입니다.


5. InMemoryChatMessageHistory (langchain_core)

langchain_core에서 제공하는 현대적인 방식. Deprecated 경고 없음.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from langchain_core.chat_history import InMemoryChatMessageHistory

chat_history = InMemoryChatMessageHistory()

# 메시지 추가
chat_history.add_user_message('안녕하세요, 저는 abc입니다')
chat_history.add_ai_message('안녕하세요, abc님! 만나서 반갑습니다')
chat_history.add_user_message('오늘 날씨가 좋네요')
chat_history.add_ai_message('네, 정말 화창한 날씨입니다')

# 메시지 조회
for msg in chat_history.messages:
    print(msg.type, msg.content)
# human 안녕하세요, 저는 abc입니다
# ai   안녕하세요, abc님! 만나서 반갑습니다
# ...

.messages 직접 조작

1
2
3
4
5
6
7
8
9
10
# 리스트처럼 직접 append 가능
chat_history.messages.append(HumanMessage(content='내 이름이 뭔가요?'))

# 또는 스프레드(*)로 기존 히스토리에 새 메시지 추가
messages = [
    *chat_history.messages,
    HumanMessage(content='내 이름이 뭔가요?')
]
llm.invoke(messages)
# → '당신의 이름은 "abc"입니다.'

▶ 포인트: *chat_history.messages로 언패킹하면 히스토리를 건드리지 않고 임시 메시지 추가가 가능합니다.


6. RunnableWithMessageHistory — 세션 기반 자동 관리

수동으로 messages에 추가하는 번거로움 없이, 세션 ID 기반으로 히스토리를 자동 관리합니다.

구조 흐름

1
2
3
4
5
6
7
8
9
10
사용자 입력 (input)
    ↓
ChatPromptTemplate
  [SystemMessage: 역할 설정]
  [MessagesPlaceholder: 히스토리 자동 삽입]
  [HumanMessage: 사용자 입력]
    ↓
LLM
    ↓
AI 응답 → 자동으로 store[session_id]에 저장

구현 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.chat_history import InMemoryChatMessageHistory

# 1. 프롬프트 템플릿 (MessagesPlaceholder가 히스토리 자리)
prompt = ChatPromptTemplate.from_messages([
    ('system', '당신은 친절한 AI 어시스턴트입니다'),
    MessagesPlaceholder(variable_name='history'),  # ← 히스토리가 여기에 자동 삽입
    ('human', '{input}')
])
chain = prompt | llm

# 2. 세션 저장소 (세션 ID → InMemoryChatMessageHistory)
store = {}
def get_session_history(session_id):
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

# 3. 히스토리 자동 관리 래퍼 생성
chain_with_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key='input',    # chain의 입력 키
    history_messages_key='history' # MessagesPlaceholder의 variable_name
)

실행 방법

1
2
3
4
5
6
7
8
9
10
11
# session_id로 어떤 사용자의 히스토리를 쓸지 지정
config = {'configurable': {'session_id': 'user_001'}}

r1 = chain_with_history.invoke({'input': '안녕하세요, 제 이름은 abc입니다'}, config=config)
# → '안녕하세요, abc님! 어떻게 도와드릴까요?'

r2 = chain_with_history.invoke({'input': '내 이름이 뭐라고 했죠?'}, config=config)
# → '당신의 이름은 abc입니다. 맞나요?'

r3 = chain_with_history.invoke({'input': '오늘 뭐하면 좋을까요?'}, config=config)
# → '오늘 할 수 있는 다양한 아이디어가 있습니다! ...'

실전 예제 — 전자제품 판매원 챗봇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
prompt = ChatPromptTemplate.from_messages([
    ('system', '당신은 친절한 전자제품 판매원입니다'),
    MessagesPlaceholder(variable_name='history'),
    ('human', '{input}')
])
chain = prompt | llm

store = {}
def get_session_history(session_id):
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

chain_with_history = RunnableWithMessageHistory(
    chain, get_session_history,
    input_messages_key='input',
    history_messages_key='history'
)

config = {'configurable': {'session_id': 'user_001'}}

r1 = chain_with_history.invoke({'input': '안녕하세요, 노트북을 사려는데 어떤게 있나요?'}, config=config)
r2 = chain_with_history.invoke({'input': '가장 인기 있는 제품의 가격이 어떻게 되나요?'}, config=config)
r3 = chain_with_history.invoke({'input': '좋아요, 2번째 제품으로 구입하겠습니다.'}, config=config)
# → AI가 "2번째 제품"이 무엇인지 히스토리를 통해 파악하여 답변

대화 기록 확인:

1
2
3
4
5
6
7
8
9
10
for msg in store['user_001'].messages:
    prefix = 'customer' if msg.type == 'human' else 'sales person'
    print(f"[{prefix}] - {msg.content[:30]}")

# [customer]     - 안녕하세요, 노트북을 사려는데 어떤게 있나요?
# [sales person] - 안녕하세요! 노트북을 구매하시려는군요...
# [customer]     - 가장 인기 있는 제품의 가격이 어떻게 되나요?
# [sales person] - 인기 있는 노트북 제품들의 가격은...
# [customer]     - 좋아요, 2번째 제품으로 구입하겠습니다.
# [sales person] - 삼성 노트북 9을 선택해 주셨군요!...

7. Window Memory — 최근 N개 턴만 유지

대화가 길어지면 오래된 내용은 버리고 최근 K턴만 메모리에 유지합니다.

방법 1: ConversationBufferWindowMemory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from langchain_classic.memory import ConversationBufferWindowMemory

window_memory = ConversationBufferWindowMemory(k=2, return_messages=True)
# k=2 → 최근 2턴(Human+AI 쌍 2개)만 유지

window_memory.save_context({'input': '첫번째, 내 이름은 abc입니다'}, {'output': '안녕하세요, abc님'})
window_memory.save_context({'input': '두번째, 나는 학생입니다'}, {'output': '학생이시군요! 멋지십니다'})
window_memory.save_context({'input': '세번째, 나는 파이썬을 좋아합니다'}, {'output': '파이썬은 정말 재미있죠!'})

window_memory.load_memory_variables({})
# → 첫번째 대화는 사라지고, 두번째 + 세번째만 남음
# {'history': [
#     HumanMessage('두번째, 나는 학생입니다'),
#     AIMessage('학생이시군요! 멋지십니다'),
#     HumanMessage('세번째, 나는 파이썬을 좋아합니다'),
#     AIMessage('파이썬은 정말 재미있죠!')
# ]}

방법 2: trim_messages (langchain_core)

1
2
3
4
5
6
7
8
9
10
11
from langchain_core.messages import trim_messages

trimmer = trim_messages(
    max_tokens=4,        # 최대 4개 메시지까지만 유지
    strategy='last',     # 최신 것부터 선택
    token_counter=len,   # 토큰 카운터 (여기서는 메시지 개수 기준)
    start_on='human'     # Human 메시지로 시작 (쌍 맞추기)
)

trimmed = trimmer.invoke(messages)
# → 최근 4개 메시지만 반환 (두번째, 세번째 대화만 남음)

방법 3: 수동 슬라이싱

1
2
3
4
5
6
7
8
messages = []
K = 2  # 유지할 턴 수

def add_turn(user_input, ai_output):
    global messages
    messages.append(HumanMessage(content=user_input))
    messages.append(AIMessage(content=ai_output))
    messages = messages[-(K * 2):]  # 최근 K턴(메시지 K*2개)만 유지

실행 결과:

1
2
3
턴 1 추가 후: [Human(첫번째), AI(첫번째)]                 → 2개
턴 2 추가 후: [Human(첫번째), AI(첫번째), Human(두번째), AI(두번째)]  → 4개 (K*2=4)
턴 3 추가 후: [Human(두번째), AI(두번째), Human(세번째), AI(세번째)]  → 4개 (첫번째 밀려남)

▶ 포인트: messages[-(K*2):]로 슬라이싱하면 K턴 윈도우를 간단하게 구현 가능.


8. Summary Memory — 오래된 대화 요약으로 압축

오래된 대화를 LLM이 요약하여 압축 보관. 디테일 일부 유지 + 토큰 절약.

방법 1: ConversationSummaryMemory (langchain_classic)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from langchain_classic.memory import ConversationSummaryMemory

summary_memory = ConversationSummaryMemory(
    llm=ChatOpenAI(model='gpt-4o-mini'),
    return_messages=False
)

conversations = [
    ('첫번째, 내 이름은 abc입니다', '안녕하세요, abc님'),
    ('두번째, 나는 학생입니다', '학생이시군요! 멋지십니다'),
    ('세번째, 나는 파이썬을 좋아합니다', '파이썬은 정말 재미있죠!')
]

for user_msg, ai_msg in conversations:
    summary_memory.save_context({'input': user_msg}, {'output': ai_msg})

result = summary_memory.load_memory_variables({})
print(result['history'])
# → 'The human introduces themselves as abc. The AI greets abc.
#    The human then states that they are a student, and the AI praises them...
#    The human adds that they like Python, to which the AI responds that Python is indeed very fun.'

▶ 주의: ConversationSummaryMemory는 영어로 요약하는 경향이 있습니다. 한국어 강제 지정이 필요하면 커스텀 구현을 권장합니다.

방법 2: 커스텀 SummaryMemory 클래스

summary_interval 턴마다 자동으로 요약을 수행하는 커스텀 메모리 클래스입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class SummaryMemory:

    def __init__(self, summary_interval=3):
        self.summary = ''              # 누적 요약 텍스트
        self.recent_messages = []      # 아직 요약되지 않은 최근 메시지들
        self.summary_interval = summary_interval  # 몇 턴마다 요약할지
        self.turn_count = 0

    def _summarize(self, text):
        """기존 요약 + 새 대화를 합쳐서 LLM으로 재요약"""
        response = llm.invoke([
            SystemMessage(content='주어진 대화 내용을 핵심만 간결하게 요약하세요. 한국어로 작성하세요'),
            HumanMessage(content=f'기존 요약:\n{self.summary}\n\n새 대화:\n{text}')
        ])
        return response.content

    def add_exchange(self, user_msg, ai_msg):
        """새 대화 턴 추가. summary_interval 도달 시 자동 요약"""
        self.recent_messages.append(f'사용자 : {user_msg}')
        self.recent_messages.append(f'AI : {ai_msg}')
        self.turn_count += 1

        if self.turn_count % self.summary_interval == 0:
            conversation_text = '\n'.join(self.recent_messages)
            self.summary = self._summarize(conversation_text)  # 요약 업데이트
            self.recent_messages = []  # 최근 메시지 초기화
            print(f' 요약 완료 턴 {self.turn_count} 에서 요약')

    def get_context(self):
        """LLM에 전달할 컨텍스트 문자열 반환"""
        parts = []
        if self.summary:
            parts.append(f'[이전 대화 요약] {self.summary}')
        if self.recent_messages:
            parts.append(f'[최근 대화]\n' + '\n'.join(self.recent_messages))
        return '\n\n'.join(parts)

동작 원리

1
2
3
4
5
6
7
8
9
10
11
12
대화 1턴: recent_messages에 추가
대화 2턴: recent_messages에 추가  ← summary_interval=2 도달!
         → recent_messages를 LLM으로 요약 → self.summary 업데이트
         → recent_messages = [] 초기화

대화 3턴: recent_messages에 추가

get_context() 호출 시:
[이전 대화 요약] 사용자가 이름과 학생임을 소개하였고, AI는 인사를 하고...
[최근 대화]
사용자 : 세번째, 나는 파이썬을 좋아합니다
AI : 파이썬은 정말 재미있죠!

실사용 예시:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
smem = SummaryMemory(summary_interval=2)

conversations = [
    ('첫번째, 내 이름은 abc입니다', '안녕하세요, abc님'),
    ('두번째, 나는 학생입니다', '학생이시군요! 멋지십니다'),   # ← 2턴: 요약 실행
    ('세번째, 나는 파이썬을 좋아합니다', '파이썬은 정말 재미있죠!')
]

for user_msg, ai_msg in conversations:
    smem.add_exchange(user_msg, ai_msg)
# → '요약 완료 턴 2 에서 요약' 출력

smem.get_context()
# → '[이전 대화 요약] 사용자가 이름과 학생임을 소개하였고...\n\n[최근 대화]\n사용자: 세번째...'

9. SummaryChatbot — 요약 메모리 통합 챗봇

SummaryMemory를 활용한 실전 챗봇 클래스입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class SummaryChatbot:

    def __init__(self, system_prompt='당신은 도움이 되는 AI 어시스턴트입니다.', summary_interval=3):
        self.system_prompt = system_prompt
        self.memory = SummaryMemory(summary_interval=summary_interval)

    def chat(self, user_input):
        # 1. 현재 메모리 컨텍스트 가져오기
        context = self.memory.get_context()

        # 2. 메시지 구성
        messages = [SystemMessage(content=self.system_prompt)]
        if context:
            messages.append(SystemMessage(content=f'대화 맥락 : \n{context}'))
        messages.append(HumanMessage(content=user_input))

        # 3. LLM 호출
        response = llm.invoke(messages)
        ai_response = response.content

        # 4. 메모리에 저장
        self.memory.add_exchange(user_input, ai_response)
        return ai_response

실전 예제 — IT 커리어 상담사

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bot = SummaryChatbot(
    system_prompt='당신은 IT 커리어 상담사입니다',
    summary_interval=2
)

questions = [
    "안녕하세요, 백엔드 개발자 3년차인데 고민이 있습니다",
    "AI/ML 분야로 전환을 고려 중인데 어떤 준비가 필요할까요?",
    "현재 Python은 잘하는데 수학과 통계 기초가 부족합니다",
    "온라인 강의와 학교 중 어떤 것이 효과적일까요?"
]

for q in questions:
    print(f'[user] {q}')
    answer = bot.chat(q)
    print(f'[상담사] {answer}')

실행 출력:

1
2
3
4
5
6
7
8
9
[user] 안녕하세요, 백엔드 개발자 3년차인데 고민이 있습니다
[상담사] 안녕하세요! 백엔드 개발자로 3년 차라니 멋지네요...

[user] AI/ML 분야로 전환을 고려 중인데 어떤 준비가 필요할까요?
 요약 완료 턴 2 에서 요약     ← summary_interval=2 도달, 자동 요약
[상담사] AI/ML 분야로의 전환을 고려하고 계시군요. 다음은 준비에 도움이 될 단계입니다:
  1. 기초 수학 및 통계학 이해 (선형 대수, 미적분학, 확률/통계)
  2. Python 심화 학습
  3. ML 기본 개념 학습 ...

챗봇 클래스 데이터 흐름

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
user_input
    ↓
memory.get_context()
  ├─ [이전 대화 요약] ...     (summary가 있을 경우)
  └─ [최근 대화] ...          (recent_messages가 있을 경우)
    ↓
messages 구성:
  [SystemMessage: 역할]
  [SystemMessage: 맥락]  ← 있을 경우만
  [HumanMessage: 질문]
    ↓
llm.invoke(messages)
    ↓
AI 응답
    ↓
memory.add_exchange(user_input, ai_response)
  → turn_count 증가
  → summary_interval 도달 시 자동 요약

10. 자주 나오는 실수 / 주의사항

❌ AIMessage를 빠뜨리는 실수

1
2
3
4
5
6
7
8
9
10
# 잘못된 예
messages.append(HumanMessage('내 이름은 abc입니다'))
response = llm.invoke(messages)
messages.append(HumanMessage('내 이름은 뭔가요?'))  # ← AIMessage 누락!

# 올바른 예
messages.append(HumanMessage('내 이름은 abc입니다'))
response = llm.invoke(messages)
messages.append(AIMessage(response.content))  # ← AI 응답도 반드시 추가
messages.append(HumanMessage('내 이름은 뭔가요?'))

❌ session_id 없이 RunnableWithMessageHistory 호출

1
2
3
4
5
6
# 잘못된 예 (config 없음)
chain_with_history.invoke({'input': '안녕'})

# 올바른 예
config = {'configurable': {'session_id': 'user_001'}}
chain_with_history.invoke({'input': '안녕'}, config=config)

❌ MessagesPlaceholder의 variable_name과 history_messages_key 불일치

1
2
3
4
5
6
7
8
9
10
11
12
# 잘못된 예
MessagesPlaceholder(variable_name='chat_history')  # 'chat_history'로 설정

RunnableWithMessageHistory(
    chain,
    get_session_history,
    history_messages_key='history'  # 'history'로 다름 → 오류!
)

# 올바른 예: 이름 일치
MessagesPlaceholder(variable_name='history')
RunnableWithMessageHistory(..., history_messages_key='history')

⚠️ ConversationBufferMemory는 Deprecated

  • langchain_classic.memory 모듈의 클래스들은 LangChain v0.2+ 에서 deprecated.
  • 신규 프로젝트에서는 langchain_core.chat_history.InMemoryChatMessageHistory 사용 권장.

⚠️ SummaryMemory의 summary_interval 선택

  • summary_interval이 너무 작으면 LLM 요약 호출이 잦아져 비용 증가.
  • summary_interval이 너무 크면 메모리 절감 효과가 없음.
  • 일반적으로 5~10 턴 권장.

11. [보충] 메모리 전략 비교

전략특징토큰 비용맥락 유실추가 LLM 호출
Buffer전체 대화 저장매우 높음없음없음
Window (k턴)최근 k턴만 유지낮음오래된 것 유실없음
Summary오래된 것 요약 압축중간일부 유실있음 (요약용)

LangGraph와의 관계

1
2
3
LangChain Chain   : 단방향 파이프라인. memory를 내부에 자동 관리.
LangGraph         : 상태(State) 기반 그래프. 개발자가 state를 직접 설계.
                    더 복잡한 multi-turn, multi-agent 시나리오에 적합.

요약 메모리 활용 시 컨텍스트 구조

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──────────────────────────────────────────────┐
│ SystemMessage: 역할 설정                      │
├──────────────────────────────────────────────┤
│ SystemMessage: 대화 맥락                      │
│   [이전 대화 요약] 요약된 내용...              │
│   [최근 대화]                                 │
│     사용자: 최근 질문1                        │
│     AI: 최근 답변1                           │
│     사용자: 최근 질문2                        │
│     AI: 최근 답변2                           │
├──────────────────────────────────────────────┤
│ HumanMessage: 현재 질문                       │
└──────────────────────────────────────────────┘

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

인기 태그