Study/AI

[LangChain] 메모리 관리

hongeeii 2025. 8. 10.
728x90
반응형

메모리 관리

GPT와 대화를 할 때 독립적으로 대화를 하기 때문에 지금까지 나눈 모든 대화를 넘김으로서 이어서 대화를 할 수 있다.

메시지 내용, 전송하는 토큰 양이 많아질 수록 비용이 많이 나올 수 있다. 따라서 최근 얼마만큼의 대화만 남기고 이전 대화를 삭제를 한다던지, 이전 대화에서 중요한 부분이 있었다면 이전 대화의 일부를 남기고 나머지는 삭제를 할 수 있다.

메시지 일부만을 남겨두기

최대 토큰 수로 자르기

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")

from langchain_core.messages import HumanMessage, SystemMessage, AIMessage, trim_messages

messages = [
    SystemMessage(content="System"),
    HumanMessage(content="Human1"),
    AIMessage(content="AI1"),
    HumanMessage(content="Human2"),
    AIMessage(content="AI2"),
    HumanMessage(content="Human3"),
    AIMessage(content="AI3")
]
 
  • 대화 많이 남기기
trimmer = trim_messages(
    max_tokens = 1000, # 최대 토큰 수를 제외한 나머지 토큰제거, Max token count of trimmed messages.
    token_counter = llm # llm의 토크나이저를 이용. token_counter=ChatOpenAI(model="gpt-4o"),
)

trimmer.invoke(messages)

=> [SystemMessage(content='System', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human1', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI1', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human2', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI2', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human3', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI3', additional_kwargs={}, response_metadata={})]
 
  • 대화 적게 남기기
# 대화 적게 남기기
trimmer = trim_messages(
    max_tokens = 30,count of trimmed messages.
    token_counter = llm
)

trimmer.invoke(messages)

=> [HumanMessage(content='Human2', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI2', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human3', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI3', additional_kwargs={}, response_metadata={})]
 

과거 대화 남기고 최근 대화 지우기

기본적으로는 trim_messages()를 사용할 때 최근 대화를 남기고 이전대화를 지운다. 이번엔 대화를 남기는 법을 알아보자.

trimmer = trim_messages(
    max_tokens = 30,
    token_counter = llm,
    strategy="first"
)

trimmer.invoke(messages)

=> [SystemMessage(content='System', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human1', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI1', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human2', additional_kwargs={}, response_metadata={})]
 

strategy를 보면 ["first", "last"]를 선택할 수 있고, default는 last 전략을 사용하고 있는것을 볼 수 있다. first를 쓰게되면 과거 대화를 남기고 최근 대화를 삭제하는것을 볼 수 있다.

시스템 메시지는 반드시 남기기

시스템 메시지는 LLM에게 어떤 역할을 할지 알려주는 중요한 메시지다보니, 과거대화를 지우고 최근대화를 남길 때도 시스템 메시지는 삭제되지 않게 하고 싶다.

# 최근 대화 남기고 과거 대화 지우는데 시스템 메시지 남기기
trimmer = trim_messages(
    max_tokens = 30,
    token_counter = llm,
    strategy="last",
    include_system= True
)

trimmer.invoke(messages)

=>[SystemMessage(content='System', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI2', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human3', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI3', additional_kwargs={}, response_metadata={})]
 

'include_system: true'로 하게 되면 시스템 메시지는 반드시 포함이 된다. default는 False인것을 확인할 수 있다.

HumanMessage 부터 시작하기

위 대화를 보면 시스템메시지가 있지만 HumanMessage가 아니라 AIMessage가 먼저 시작이 되고 있다. 요청없이 응답을 보낸셈인데 HumanMessage를 먼저 보낸다면 더 자연스럽게 대화가 된다.

# 최근 대화 남기고 과거 대화 지우는데 시스템 메시지도 남기고 HumanMessage 부터 시작하기
trimmer = trim_messages(
    max_tokens = 30,
    token_counter = llm,
    strategy="last",
    include_system= True,
    start_on="human"
)

trimmer.invoke(messages)

=> [SystemMessage(content='System', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='Human3', additional_kwargs={}, response_metadata={}),
 AIMessage(content='AI3', additional_kwargs={}, response_metadata={})]
 
start_on

Can be specified as string names (e.g. "system", "human", "ai", ...) or as BaseMessage classes (e.g. SystemMessage, HumanMessage, AIMessage, ...). Can be a single type or a list of types. Default is None.
 

주석을 확인하면 'start_on'을 통해 먼저 시작할 메시지를 정의할 수 있다. (system, human, ai) 또는 (SystemMessage, HumanMessage, AIMessage)로 사용하면 된다.

728x90
반응형

추천 글