איך לשמור שיחות ב LangGraph
בוובינר אתמול הראיתי את לנגגרף ואת עיקרי העבודה אתה אבל בדוגמה האחרונה נפלה טעות. הנה הקוד המקורי שכתבתי עם הטעות:
from langgraph.graph import StateGraph, MessagesState, START, END
from google.colab import userdata
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.messages import HumanMessage
# --- setup ---
api_key = userdata.get("GEMINI_API_KEY")
llm = ChatGoogleGenerativeAI(
model="gemini-2.5-flash",
temperature=1.0,
google_api_key=api_key,
)
class GraphState(MessagesState):
pass
# --- graph node ---
async def chat_node(state: GraphState):
response = await llm.ainvoke(state["messages"])
return {
"messages": [response]
}
# --- build graph ---
graph = StateGraph(GraphState)
graph.add_node("chat", chat_node)
graph.add_edge(START, "chat")
graph.add_edge("chat", END)
app = graph.compile()
# --- interactive loop (Colab-safe) ---
state: GraphState = {"messages": []}
try:
while True:
user_input = input("You: ").strip()
state = await app.ainvoke(
{"messages": [HumanMessage(content=user_input)]},
state
)
print("AI:", state["messages"][-1].content)
except KeyboardInterrupt:
print("\nExiting chat. Goodbye!")
התוכנית הזו אמורה היתה להציג ממשק שיחה מתמשך בו בן אדם מדבר עם AI וכל הודעה מתווספת למערך הודעות שהולך וגדל ככל שהשיחה ממשיכה. מהר מאוד ראינו שזה לא עבד וה AI מתעלם מהודעות ישנות. בואו נראה מה היתה הבעיה ומה התיקון.
1. הבעיה - חתימה לא נכונה
במקום להסתכל בתיעוד של לנגגרף כשכתבתי את התוכנית שאלתי את ה AI איך לשמור הודעות ישנות והוא הציע לי את ה API הבא שלא קיים בספריה:
state = await app.ainvoke(
{"messages": [HumanMessage(content=user_input)]},
state
)
ההצעה של ChatGPT היתה להעביר את ההודעות הישנות בתור פרמטר שני ל ainvoke וכך ההפעלה של הגרף תיקח את כל ההודעות החדשות והישנות ותחבר ביניהן. ביקשתי לראות את התיעוד הרלוונטי ול ChatGPT לא היתה בעיה להזות תיעוד של הפונקציה.
למרות שאין חתימה כזו פייתון לא אוכף מדיניות טיפוסים ולכן הקוד רץ ללא שגיאות פשוט התעלם מהודעות ישנות.
2. מה בכל זאת צריך לעשות
הדרך הנכונה לזכור הודעות ישנות בהחלט קשורה לפרמטר השני של ainvoke אבל דורשת קצת יותר עבודה. למעשה יש שתי אפשרויות מרכזיות:
אפשר לוותר על הפרמטר השני ולשמור לבד את ההיסטוריה. אחרי כל הרצה של הגרף ניקח את ההודעה האחרונה של ה AI, נוסיף אותה למערך ההיסטוריה שלנו ונעביר מערך זה בתור הפרמטר הראשון ל ainvoke.
בלנגגרף עצמה יש מנגנון ניהול היסטוריה מובנה בשם MemorySaver. מנגנון זה שומר את הסטייט של כל גרף בזכרון ומאפשר להמשיך את התהליך עם אותו סטייט שמור.
בשביל להשתמש ב MemorySaver עלינו ליצור אותו, להעביר אותו בעת יצירת הגרף ולבחור מזהה לשיחה. סך הכל מדובר בשלושה שינוים:
# 1. Create MemorySaver
checkpointer = MemorySaver()
# 2. Assign it to the graph
app = graph.compile(checkpointer=checkpointer)
# 3. Pass the id as the second argument to ainvoke
state = await app.ainvoke(
{"messages": [HumanMessage(content=user_input)]},
config={"configurable": {"thread_id": "user-123"}}
)
את thread_id אתם קובעים מבחוץ לפי התהליך - אם אתם רוצים להתחיל שיחה חדשה תקבעו thread_id חדש. בשביל להמשיך שיחה קיימת בוחרים את המזהה של השיחה הקיימת. התוכנית המלאה היא לכן:
from langgraph.graph import StateGraph, MessagesState, START, END
from google.colab import userdata
from langgraph.checkpoint.memory import MemorySaver
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.messages import HumanMessage
# --- setup ---
api_key = userdata.get("GEMINI_API_KEY")
llm = ChatGoogleGenerativeAI(
model="gemini-2.5-flash",
temperature=1.0,
google_api_key=api_key,
)
checkpointer = MemorySaver()
class GraphState(MessagesState):
pass
# --- graph node ---
async def chat_node(state: GraphState):
response = await llm.ainvoke(state["messages"])
return {
"messages": [response]
}
# --- build graph ---
graph = StateGraph(GraphState)
graph.add_node("chat", chat_node)
graph.add_edge(START, "chat")
graph.add_edge("chat", END)
app = graph.compile(checkpointer=checkpointer)
# --- interactive loop (Colab-safe) ---
state: GraphState = {"messages": []}
try:
while True:
user_input = input("You: ").strip()
state = await app.ainvoke(
{"messages": [HumanMessage(content=user_input)]},
config={"configurable": {"thread_id": "user-123"}}
)
print("AI:", state["messages"][-1].content)
except KeyboardInterrupt:
print("\nExiting chat. Goodbye!")
שבוע הבא נדבר על AgentCore ונראה איך להעלות את סוכן הלנגגרף שלנו לענן של AWS. מוזמנים להצטרף.