단기 메모리는 현재 대화를 추적합니다. 에이전트가 세 메시지 전에 "내 이름은 Alice입니다"를 기억하게 하고, 긴 대화에서 컨텍스트 창이 넘치지 않도록 방지합니다.
LLM은 제한된 컨텍스트 창을 가지고 있습니다. 대화가 길어질수록:
턴 1: 사용자: "내 이름은 Alice입니다" ← 10 토큰
턴 50: 사용자: "내 이름이 뭐였지?" ← 총 50,000 토큰
에이전트: "모르겠어요" ← 컨텍스트 오버플로우, 이전 메시지 손실
단순한 해결책은 트레이드오프가 있습니다:
| 접근 방식 | 문제점 |
|---|---|
| 모든 것 유지 | 컨텍스트 창 초과, 비용 폭증 |
| 오래된 메시지 삭제 | 중요한 컨텍스트 손실 ("내 이름은 Alice입니다") |
| 고정 슬라이딩 윈도우 | 임의의 잘림, 중요한 정보 손실 가능 |
ShortTermMemoryManager가 컨텍스트를 지능적으로 관리합니다:

| 기능 | 하는 일 |
|---|---|
| 토큰 인식 | 메시지 수가 아닌 실제 토큰 수 추적 |
| 스마트 트리밍 | 여러 전략: 가장 오래된 것부터, 시작부터, 끝부터 |
| 요약 | 필요할 때 오래된 메시지를 요약으로 압축 |
| 내장 | ChatBot이 자동으로 처리—추가 코드 불필요 |
pip install spoon-ai
export OPENAI_API_KEY="your-key"
import asyncio
from spoon_ai.chat import ChatBot
# ChatBot은 자동 트리밍 기능이 있는 내장 단기 메모리를 포함합니다
llm = ChatBot(model_name="gpt-5.1-chat-latest", llm_provider="openai")
async def main():
await llm.ask([{"role": "user", "content": "내 이름은 Alice입니다"}])
await llm.ask([{"role": "user", "content": "프랑스의 수도는 어디인가요?"}])
response = await llm.ask([{"role": "user", "content": "내 이름이 뭐였지?"}]) # "Alice"를 기억함
print(response)
asyncio.run(main())
ChatBot의 자동 처리 이상의 세밀한 제어가 필요한 경우, ShortTermMemoryManager를 직접 사용하세요:
import asyncio
from spoon_ai.memory.short_term_manager import ShortTermMemoryManager, TrimStrategy
from spoon_ai.schema import Message
manager = ShortTermMemoryManager()
history = [
Message(id="u1", role="user", content="안녕하세요!"),
Message(id="a1", role="assistant", content="안녕하세요 — 무엇을 도와드릴까요?"),
Message(id="u2", role="user", content="DeFi가 뭐예요?"),
]
# 토큰 예산에 따라 메시지 목록 트리밍
trimmed = asyncio.run(
manager.trim_messages(
messages=history,
max_tokens=48,
strategy=TrimStrategy.FROM_END,
keep_system=True,
)
)
# 모델 호출 전 히스토리 요약
llm_ready, removals, summary = asyncio.run(
manager.summarize_messages(
messages=history,
max_tokens_before_summary=48,
messages_to_keep=2,
summary_model="anthropic/claude-3.5-sonnet",
llm_manager=chatbot.llm_manager,
llm_provider=chatbot.llm_provider,
existing_summary=chatbot.latest_summary() or "",
)
)
llm_ready — LLM에 전달할 수 있는 압축된 히스토리
removals — RemoveMessage 지시문 목록: spoon_ai.graph.reducers.add_messages를 사용하여 지속된 히스토리에 제거 사항을 적용하세요.
참고: summarize_messages()와 ChatBot.ask() 모두 구성된 LLM을 호출합니다. 이러한 예제가 끝까지 실행될 수 있도록 chatbot.llm_manager/chatbot.llm_provider (및 필요한 API 키나 env 변수)가 설정되어 있는지 확인하세요.
from spoon_ai.chat import ChatBot
from spoon_ai.graph.reducers import add_messages
chatbot = ChatBot(enable_short_term_memory=True)
history = [
Message(id="u1", role="user", content="안녕하세요!"),
Message(id="a1", role="assistant", content="안녕하세요 — 무엇을 도와드릴까요?"),
Message(id="u2", role="user", content="DeFi가 뭐예요?"),
]
# 최신 어시스턴트 메시지 제거
assistant_ids = [msg.id for msg in history if msg.role == "assistant"]
remove_last = chatbot.remove_message(assistant_ids[-1])
# 또는 전체 히스토리 지우기
remove_all = chatbot.remove_all_messages()
# 지속된 히스토리에 지시문 적용
updated_history = add_messages(history, [remove_last])
cleared_history = add_messages(history, [remove_all])
add_messages()는 제거 지시문을 기존 히스토리에 병합하여 대상 항목(또는 전체 전사본)을 삭제합니다.
이는 단기 메모리 관리자가 요약이 오래된 턴을 트리밍할 때 RemoveMessage 항목을 내보내는 방식과 동일합니다.
그래프가 실행될 때마다 최신 스냅샷(메시지 및 메타데이터)을 검색하고, 전체 체크포인트 히스토리를 반복하거나, 외부 소비자를 위한 CheckpointTuple을 읽을 수 있습니다. 이를 통해 메모리 동작을 디버깅하거나, 모든 체크포인트에서 재생하거나, 상태를 지속적 저장소에 동기화하기가 쉬워집니다. 아래 예제는 최신 요약을 가져오고, 모든 체크포인트를 나열하며, 튜플 스타일 페이로드를 보는 방법을 보여줍니다.
config = {"configurable": {"thread_id": "memory_demo_thread"}}
snapshot = graph.get_state(config)
print("최신 체크포인트:", snapshot.metadata.get("checkpoint_id"))
for snap in graph.get_state_history(config):
print("히스토리 id:", snap.metadata.get("checkpoint_id"))
checkpoint_tuple = graph.checkpointer.get_checkpoint_tuple(config)
print("체크포인트 튜플:", checkpoint_tuple)
for entry in graph.checkpointer.iter_checkpoint_history(config):
print("튜플 히스토리 항목:", entry)
컴파일된 그래프(CompiledGraph)를 사용하는 경우, 대신 graph.graph.get_state(config)와 graph.graph.get_state_history(config)를 호출하세요. 위 스니펫은 graph가 StateGraph라고 가정합니다.