Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Használja a langchain-azure-ai jelölőt és a Foundry Memory-t hosszú távú memória hozzáadásához az alkalmazásokhoz. Ebben a cikkben létrehoz egy memóriaalapú láncot, tárolja a felhasználói beállításokat, visszahívja őket egy új munkamenetben, és közvetlen memória-lekérdezéseket futtat.
Ez a minta a LangChain és a LangGraph alkalmazások esetében is működik. Az alapvető ötlet a rövid távú csevegési előzmények megőrzése a futtatókörnyezetben, és az Foundry Memory használata hosszú távú tárolóként felhasználói szintű környezetként.
Az Foundry Memory a hosszú távú memóriára összpontosít. Rövid távú, lépésről-lépésre állapot megtartása a LangChain vagy LangGraph futási környezeti állapotában.
Előfeltételek
- Egy Azure előfizetés. Hozzon létre egyet ingyen.
- Egy Foundry-projekt.
- Üzembe helyezett Microsoft Foundry-csevegési modell memórialekéréshez.
- Ez az oktatóanyag a "gpt-4.1"-t használja.
- Üzembe helyezett csevegőmodell és beágyazási modell a memóriatárolóhoz.
- Ez az oktatóanyag a
text-embedding-3-large-t használja.
- Ez az oktatóanyag a
- Python 3.10-et vagy újabb verziót.
- Azure CLI be van jelentkezve (
az login), hogyDefaultAzureCredentialhitelesíthesse magát Azure AI Developer szerepkörrel.
A környezet konfigurálása
Telepítse az oktatóanyaghoz szükséges csomagokat. A LangChain és a LangGraph integrációjához a langchain-azure-ai, a memóriatárolók kezeléséhez a azure-ai-projects, és a hitelesítéshez a azure-identity használható.
pip install -U "langchain-azure-ai" azure-ai-projects
Állítsa be az oktatóanyagban használt környezeti változókat:
export AZURE_AI_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
A memóriamodell ismertetése
Az Foundry Memória két hosszú távú memóriatípust tárol és kér le:
- Felhasználói profil memóriája: stabil felhasználói adatok és preferenciák, például előnyben részesített név vagy táplálkozási korlátozások.
- Csevegőösszegző memória: a korábbi vitafórumok összefoglalói.
A memória a "hatókör" gondolatát használja az információk particionálására, hogy azok folyamatosan tárolhatók és lekérhetők legyenek. A hatókörök olyanok, mint azonosítók vagy kulcsok az információk rendszerezéséhez.
- A hosszú távú memória stabil identitásaként használhatja a felhasználói azonosítókat . Tartsa ugyanazt a munkamenetek során az adott felhasználó számára.
- A munkamenet-azonosítókat rövid távú beszélgetési identitásként használhatja. Módosítsa csevegés közben.
- Az erőforrás-azonosítókat több felhasználó hosszú távú memóriájának stabil azonosítójaként használhatja.
Ez az elkülönítés lehetővé teszi, hogy az alkalmazás a nem kapcsolódó beszélgetések összekeverése nélkül jegyezze fel a munkamenetek felhasználói beállításait.
A memóriatároló létrehozása
Az első lépések előtt létre kell hoznia egy memóriatárolót. Ehhez a művelethez használja a Microsoft Foundry-projektek SDK-azure-ai-projects.
import os
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
MemoryStoreDefaultDefinition,
MemoryStoreDefaultOptions,
)
from azure.core.exceptions import ResourceNotFoundError
from azure.identity import DefaultAzureCredential
endpoint = os.environ["AZURE_AI_PROJECT_ENDPOINT"]
credential = DefaultAzureCredential()
client = AIProjectClient(endpoint=endpoint, credential=credential)
store_name = "lc-integration-test-store"
try:
store = client.beta.memory_stores.get(store_name)
print(f"✓ Memory store '{store_name}' already exists")
except ResourceNotFoundError:
print(f"Creating memory store '{store_name}'...")
definition = MemoryStoreDefaultDefinition(
chat_model="gpt-4.1", # Change for your LLM model
embedding_model="text-embedding-3-large", # Change for your emebddings model
options=MemoryStoreDefaultOptions(
user_profile_enabled=True,
chat_summary_enabled=True,
),
)
store = client.beta.memory_stores.create(
name=store_name,
description="Long-term memory store",
definition=definition,
)
print(f"✓ Memory store '{store_name}' created successfully")
✓ Memory store 'lc-integration-test-store' created successfully
A kódrészlet leírása: Csatlakozik az Foundry-projekthez, lekéri vagy létrehozza a memóriatárolót, és lehetővé teszi a felhasználói profilt, valamint a csevegések összegzését.
Memória használata a LangGraphban és a LangChainben
Az Foundry Memory két objektum bevezetésével integrálható a LangGraphban és a LangChainben:
- Az osztály
langchain_azure_ai.chat_message_history.AzureAIMemoryChatMessageHistorylétrehoz egy memóriaalapú csevegési előzményt. - Az osztály
langchain_azure_ai.retrievers.AzureAIMemoryRetrieverlehetővé teszi az emlékek lekérését a csevegőüzenetek előzményeiből.
Általában a következő gyakorlati lekérési stratégiákat használhatja velük:
- A válaszok személyre szabásához kérje le a felhasználói profil memóriáját a beszélgetés korai szakaszában.
- Kérje le a csevegés összefoglaló memóriáját az aktuális fordulat alapján a releváns korábbi környezet helyreállításához.
Példa: Munkamenet-tudatos memóriaréteg hozzáadása
Ebben a példában egyetlen futtathatót hozunk létre a LangChainben, amely lekéri a releváns hosszú távú memóriát, beszúrja a parancssorba, és rövid távú csevegési előzményekkel és hosszú távú memóriával együtt hajtja végre a modellt.
Nézzük meg, hogyan valósíthatja meg:
A csevegőüzenetek előzményeinek létrehozása
Ez a példa egy stabil user_id memóriatartományt használ. Használja a session_id-t az egyes munkameneteken belüli beszélgetési környezethez.
from langchain_azure_ai.chat_history import AzureAIMemoryChatMessageHistory
from langchain_azure_ai.retrievers import AzureAIMemoryRetriever
from langchain_core.chat_history import InMemoryChatMessageHistory
_session_histories: dict[tuple[str, str], AzureAIMemoryChatMessageHistory] = {}
def get_session_history(user_id: str, session_id: str) -> AzureAIMemoryChatMessageHistory:
"""Get or create a session history for a user and session.
Args:
user_id: Stable user identifier (used as scope in Foundry Memory)
session_id: Ephemeral session identifier
Returns:
AzureAIMemoryChatMessageHistory instance
"""
cache_key = (user_id, session_id)
if cache_key not in _session_histories:
_session_histories[cache_key] = AzureAIMemoryChatMessageHistory(
project_endpoint=endpoint,
credential=credential,
store_name=store_name,
scope=user_id,
base_history=InMemoryChatMessageHistory(),
update_delay=0, # TEST MODE: process updates immediately (default ~300s)
)
return _session_histories[cache_key]
def get_foundry_retriever(user_id: str, session_id: str) -> AzureAIMemoryRetriever:
"""Get a retriever tied to the cached session history.
This preserves incremental search state across turns.
Args:
user_id: Stable user identifier
session_id: Ephemeral session identifier
Returns:
AzureAIMemoryRetriever instance
"""
return get_session_history(user_id, session_id).get_retriever(k=5)
A kódrészlet leírása: Páronként (user_id, session_id) létrehoz egy memóriaalapú előzményt és lekérőt, és gyorsítótárazza őket, így a lekérési állapot több fordulóban is megmarad ugyanabban a munkamenetben. Ebben az útmutatóban azonnal láthatóvá teszi a update_delay=0 memóriafrissítéseket.
Termelési környezetben használja az alapértelmezett késleltetést, hacsak nincs kifejezetten szüksége azonnali kinyerésre.
session_histories használatával elkerülhető, hogy folyamatosan újra létre kell hoznia az objektumokat.
A futtatható összeállítása memória lekéréssel
Hozzunk létre egy futtathatót a hurok implementálásához:
from typing import Any
import os
from langchain.chat_models import init_chat_model
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import ConfigurableFieldSpec, RunnablePassthrough
from langchain_core.runnables.history import RunnableWithMessageHistory
llm = init_chat_model("azure_ai:gpt-4.1", temperature=0.7)
prompt = ChatPromptTemplate.from_messages(
[
("system", "You are helpful and concise. Use prior memories when relevant."),
MessagesPlaceholder("history"),
("system", "Memories:\n{memories}"),
("human", "{question}"),
]
)
def chain_for_session(user_id: str, session_id: str) -> RunnableWithMessageHistory:
"""Create a chain with message history for a specific user and session.
Args:
user_id: Stable user identifier
session_id: Ephemeral session identifier
Returns:
Runnable chain with message history
"""
retriever = get_foundry_retriever(user_id, session_id)
def format_memories(x: dict[str, Any]) -> str:
"""Retrieve and format memories as text."""
docs = retriever.invoke(x["question"])
return (
"\n".join([doc.page_content for doc in docs])
if docs
else "No relevant memories found."
)
# Use RunnablePassthrough.assign to add memories to the input dict
# RunnableWithMessageHistory will inject history automatically
chain = RunnablePassthrough.assign(memories=format_memories) | prompt | llm
chain_with_history = RunnableWithMessageHistory(
chain,
get_session_history=get_session_history,
input_messages_key="question",
history_messages_key="history",
history_factory_config=[
ConfigurableFieldSpec(
id="user_id",
annotation=str,
name="User ID",
description="Unique identifier for the user.",
default="",
is_shared=True,
),
ConfigurableFieldSpec(
id="session_id",
annotation=str,
name="Session ID",
description="Unique identifier for the session.",
default="",
is_shared=True,
),
],
)
return chain_with_history
Mit csinál ez a kódrészlet: Létrehoz egy futtathatót, amely beilleszti a beolvasott memóriákat a promptba, majd RunnableWithMessageHistory segítségével becsomagolja, hogy a csevegési előzmények és a hosszú távú memória együttműködjön.
Ez a minta determinisztikussá teszi az utasítást: minden egyes fordulat explicit módon tartalmazza a beolvasott memóriát a Memories szakaszban.
Munkameneteken átívelő gyakorlati forgatókönyv futtatása
Ez a forgatókönyv a hosszú távú memória teljes értékét mutatja be:
- Az A munkamenetben a felhasználó megosztja a beállításokat.
- A B munkamenetben az alkalmazás automatikusan visszahívja ezeket a beállításokat.
import time
user_id = "user_001"
session_id = "session_2026_02_10_001"
chain = chain_for_session(user_id, session_id)
# 4) Session A: seed preferences (long-term memory extraction happens async)
print(
"\n=== Turn 1 (Session A): Introduce a preference "
"(will be extracted into long-term memory) ==="
)
r1 = chain.invoke(
{"question": "Hi! Call me JT. I prefer dark roast coffee and budget trips."},
config={"configurable": {"user_id": user_id, "session_id": session_id}},
)
print("ASSISTANT:", r1.content)
print("\n=== Turn 2 (Session A): Add another preference ===")
r2 = chain.invoke(
{
"question": "Also, I usually drink green tea in the afternoon "
"and I like staying in hostels."
},
config={"configurable": {"user_id": user_id, "session_id": session_id}},
)
print("ASSISTANT:", r2.content)
# Because we set update_delay=0, extraction should happen immediately for demo.
# If you use the default delay, you may need to wait before querying from new session.
time.sleep(60)
# 5) Cross-session test: same user_id, new session_id
session_id_b = "session_2026_02_10_002"
chain_b = chain_for_session(user_id, session_id_b)
print("\n=== Turn 3 (Session B): New session should recall coffee preference ===")
r4 = chain_b.invoke(
{"question": "Remind me of my coffee preference and travel style."},
config={"configurable": {"user_id": user_id, "session_id": session_id_b}},
)
print("ASSISTANT:", r4.content)
print("\n=== Turn 4 (Session B): Retrieve another preference ===")
r5 = chain_b.invoke(
{
"question": "What do I usually drink in the afternoon, "
"and where do I like to stay?"
},
config={"configurable": {"user_id": user_id, "session_id": session_id_b}},
)
print("ASSISTANT:", r5.content)
=== Turn 1 (Session A) ===
ASSISTANT: Nice to meet you, JT. I noted that you prefer dark roast coffee and budget trips.
=== Turn 2 (Session A) ===
ASSISTANT: Got it. I also noted that you usually drink green tea in the afternoon and prefer hostels.
=== Turn 3 (Session B) ===
ASSISTANT: Your coffee preference is dark roast, and your travel style is budget trips.
=== Turn 4 (Session B) ===
ASSISTANT: You usually drink green tea in the afternoon, and you like staying in hostels.
A kódrészlet leírása: Az A munkamenet felhasználói beállításainak magolása, a B munkamenet indítása ugyanazzal a felhasználóval, és azt mutatja, hogy az alkalmazás vissza tudja hívni a munkamenetek korábbi beállításait.
Példa: Memória közvetlen lekérdezése nem csevegéses használati esetekhez
Használjon alkalmi leolvasót, ha közvetlen memóriaolvasást szeretne a beszélgetési folyamaton kívül, például személyre szabási köztes szoftverben vagy profilvizsgálati eszközökben.
adhoc = AzureAIMemoryRetriever(
project_endpoint=endpoint,
credential=credential,
store_name=store_name,
scope=user_id,
k=5,
)
print("\n=== Turn 5 (Ad-hoc): Direct retriever query without session history ===")
adhoc_docs = adhoc.invoke("What are my drinking preferences?")
for i, doc in enumerate(adhoc_docs, start=1):
print(f"MEMORY {i}:", doc.page_content)
MEMORY 1: Prefers dark roast coffee.
MEMORY 2: Prefers budget trips.
MEMORY 3: Usually drinks green tea in the afternoon.
MEMORY 4: Likes staying in hostels.
A kódrészlet leírása: Az aktuális hatókör közvetlen memóriakeresését futtatja. Minden emlék lekérésre kerül (korlátozva k), de relevancia szerint van rendezve.
Ezt a mintát akkor használja, ha közvetlen memóriaolvasásra van szüksége olyan funkciókhoz, mint a profilkártyák, a személyre szabási köztes szoftver vagy a munkafolyamat-útválasztás.
Példa: Memória használata grafikonokon
A LangGraph ugyanazt a fogalmi mintát használja:
- Tartsd stabilan a
user_id-t a hosszú távú memória érdekében. - Rövid távú szálkörnyezethez használja
thread_id(vagy azzal egyenértékű). - A modellcsomópont meghívása előtt kérje le a memóriát.
Ha már rendelkezik egy StateGraph, illessze be az adatlekérést a modellcsomópontjába, és csatolja a memóriaszöveget a modell bemenetéhez. Egy másik tipikus stratégia az előmodell-horog használata.
from langgraph.graph import MessagesState
def call_model_with_foundry_memory(state: MessagesState, config: dict):
user_id = config["configurable"]["user_id"]
session_id = config["configurable"]["thread_id"]
query = state["messages"][-1].content
retriever = get_foundry_retriever(user_id, session_id)
docs = retriever.invoke(query)
memory_text = "\n".join(d.page_content for d in docs) if docs else ""
response = llm.invoke(
[
{"role": "system", "content": "Use prior memories when relevant."},
{"role": "system", "content": f"Memories:\n{memory_text}"},
*state["messages"],
]
)
return {"messages": [response]}
Mit csinál ez a kódrészlet: Megjelenít egy LangGraph csomópont mintázatot, amely lekéri a Foundry memóriát a jelenlegi lépéshez, és beilleszti azt a modell bemenetébe.
A LangGraph memóriafogalmainak szélesebb körű ismertetése:
Az előzetes verzió korlátainak és a működési útmutatónak a megismerése
Az éles környezetbe való áttérés előtt ellenőrizze az alábbi korlátozásokat:
- A memória előzetes verzióban van, és a viselkedés változhat.
- A memóriához kompatibilis csevegési és beágyazási üzembe helyezésekre van szükség.
- A kvóták tárolónként és hatókörönként érvényesek, beleértve a keresési és frissítési kérelmek arányát is.
Tervezze meg a memóriamérgezés vagy a gyorsinjektálási kísérletek védelmi vezérlőit is. Ellenőrizze a nem megbízható bemeneteket, mielőtt befolyásolják a tárolt memóriát.
Erőforrások törlése
A minták futtatása után törölje a hatókört, hogy a tesztadatok ne szivárogjanak be a jövőbeli futtatásokba.
result = client.memory_stores.delete_scope(name=store_name, scope=user_id)
print(
f"Deleted {getattr(result, 'deleted_count', 'all')} memories "
f"for scope '{user_id}'."
)
Deleted 4 memories for scope 'user_001'.