Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Importante
Gli elementi contrassegnati (anteprima) in questo articolo sono attualmente in anteprima pubblica. Questa anteprima viene fornita senza un contratto di servizio e non è consigliabile per i carichi di lavoro di produzione. Alcune funzionalità potrebbero non essere supportate o potrebbero avere funzionalità limitate. Per ulteriori informazioni, vedere Condizioni supplementari per l'uso delle versioni di anteprima di Microsoft Azure.
In questa guida introduttiva, si fornisce a un agente ospitato una memoria semantica persistente basata su un archivio di memoria Foundry. Senza memoria, ogni conversazione inizia da zero. Con un archivio di memoria, l'agente mantiene fatti stabili su un utente, ad esempio un nome o una preferenza alimentare, e li richiama nelle sessioni successive.
Completi due parti:
-
Effettuare il provisioning di un archivio di memoria e collegarlo all'agente. Nel flusso di Azure Developer CLI, un hook di provisioning integrato viene eseguito dopo
azd provision. Nel percorso Python si crea l'archivio direttamente con l'SDK. L'archivio usa un modello di chat e un modello di incorporamento per estrarre e indicizzare le memorie del profilo utente. -
Distribuire un agente ospitato che legge e scrive nell'archivio tramite
FoundryMemoryProvider. Il provider recupera le memorie pertinenti prima di ogni chiamata al modello e aggiorna l'archivio con nuove informazioni dopo ogni turno.
Il codice dell'agente, il provider di memoria e l'autenticazione provengono dall'esempio di memoria Foundry, in modo da concentrarsi sul flusso di lavoro anziché sull'implementazione.
Se si usa un agente di codifica come GitHub Copilot, la competenza Microsoft Foundry consente di effettuare il provisioning dell'archivio memoria, collegarlo all'agente ospitato e testare il comportamento di richiamo.
Prerequisiti
Questo argomento di avvio rapido si basa sulla toolchain dell'agente ospitato. Completare prima i prerequisiti nell'Avvio rapido dell'agente ospitato, che illustrano la sottoscrizione Azure, i ruoli del progetto, Python, Azure Developer CLI (azd) e l'estensione microsoft.foundry.
Si usa Azure Developer CLI in questo percorso per creare la struttura di base dell'esempio, effettuare il provisioning dell'archivio di memoria tramite un hook incluso postprovision, eseguire l'agente in locale e distribuirlo.
In questo percorso si usa l'SDK di Python per creare l'archivio memoria con AIProjectClient.beta.memory_stores.create(...), caricare il codice dell'agente ospitato come nuova versione, instradare temporaneamente il traffico e verificare che lo stesso utente connesso venga memorizzato tra chiamate separate.
Installare i pacchetti Python usati in questo percorso:
pip install "azure-ai-projects>=2.3.0" azure-identity python-dotenv
È necessaria anche una distribuzione di un modello di embedding nel progetto Foundry, ad esempio text-embedding-3-small. L'archivio memoria lo usa per indicizzare le memorie. Il modello di chat dell'agente, ad esempio gpt-4o, può essere la distribuzione che già usi per gli agenti ospitati.
L'identità deve disporre del ruolo Utente Foundry nell'ambito del progetto Foundry tramite i prerequisiti per l'agente ospitato e deve inoltre disporre del ruolo Utente Servizi cognitivi OpenAI nello stesso ambito. L'archivio di memoria usa l'accesso al piano dati del progetto Foundry e la distribuzione del modello di embedding. Senza il ruolo OpenAI, le scritture di memoria hanno esito negativo con un 401 errore e l'archivio rimane vuoto.
Importante
I ruoli di Controllo degli accessi in base al ruolo di Foundry sono stati recentemente rinominati. Foundry User, Foundry Owner, Foundry Account Owner e Foundry Project Manager erano precedentemente denominati Azure AI User, Azure AI Owner, Azure AI Account Owner e Azure AI Project Manager. È possibile che i nomi precedenti vengano visualizzati in alcune posizioni durante l'esecuzione della ridenominazione. Gli ID ruolo e le autorizzazioni di base sono invariati dalla ridenominazione.
Passaggio 1: Inizializzare l'agente ospitato
Inizializzare un agente ospitato dall'esempio di memoria Foundry. L'inizializzazione copia i file di esempio, inclusi lo script di provisioning dell'archivio di memoria e l'hook di provisioning, in una nuova directory di servizio sotto src/. Eseguire questi comandi in una directory vuota.
mkdir my-memory-agent
cd my-memory-agent
azd ai agent init -m "https://github.com/microsoft-foundry/foundry-samples/blob/main/samples/python/hosted-agents/agent-framework/responses/13-foundry-memory/azure.yaml"
Segui le istruzioni per selezionare la sottoscrizione, il progetto e una distribuzione del modello. Se non hai un progetto Foundry, azd ai agent init ti guida nella creazione di un progetto.
Passaggio 2: Abilitare il provisioning con un solo comando
L'esempio include un postprovision hook che crea l'archivio di memoria e lo collega automaticamente all'agente ogni volta che si esegue azd provision. Registra l'hook al livello principale del file azure.yaml generato da azd ai agent init.
Aprire azure.yaml e aggiungere il blocco di primo livello seguente. Sostituire <agent-name> con la cartella del servizio creata dall'inizializzazione in src/:
hooks:
postprovision:
posix:
shell: sh
run: ./src/<agent-name>/hooks/postprovision.sh
windows:
shell: pwsh
run: ./src/<agent-name>/hooks/postprovision.ps1
L'hook trova automaticamente la propria posizione ed è idempotente. Funziona correttamente a prescindere dalla directory da cui azd lo richiama, e le esecuzioni successive lasciano inalterato un archivio esistente.
Annotazioni
Registrare postprovision nel livello superiore di azure.yaml. Gli hook con ambito di servizio supportano solo il pacchetto e il ciclo di vita della distribuzione, non il provisioning.
Passaggio 3: Effettuare il provisioning dell'archivio di memoria e delle risorse Azure
Puntare l'hook alla distribuzione del modello di incorporamento che alimenta la memoria semantica dell'archivio:
azd env set AZURE_AI_EMBEDDING_MODEL_DEPLOYMENT_NAME "text-embedding-3-small"Provvigione:
azd provision
azd provision crea o riutilizza il progetto Foundry e la distribuzione del modello di chat. Quindi il postprovision gancio:
- Crea l'archivio di memoria con la funzionalità profilo utente abilitata e ne verifica la presenza sul servizio.
- Imposta
MEMORY_STORE_NAMEin modo che l'agente legga e scriva tale archivio. L'hook salva il nome nell'ambienteazdper le esecuzioni locali e nell'ambiente del servizio inazure.yaml, in modo cheazd deploylo invii al container.
Nel percorso della riga di comando non viene mostrato un comando separato create memory store perché l'hook incluso gestisce quella logica di creazione come parte di azd provision.
L'hook imposta come predefinito il nome dell'archivio su agent_framework_memory. Per usare un nome diverso, impostarlo prima di effettuare il provisioning:
azd env set MEMORY_STORE_NAME "<your-store-name>"
Passaggio 4: Eseguire l'agente a livello locale
Avvia l'agente:
azd ai agent runQuesto comando crea un ambiente virtuale, installa le dipendenze e gestisce l'agente in
http://localhost:8088. L'hook impostaMEMORY_STORE_NAMEgià nell'ambienteazd, quindi non è necessaria una configurazione aggiuntiva. I pacchetti di anteprima possono generare avvisi pip durante l'installazione. Questi avvisi non sono bloccanti.In un terminale separato, indicare all'agente un fatto su se stessi:
azd ai agent invoke --local "Hi! My name is Linda and I'm vegetarian. Please remember that."Avviare una nuova sessione e confermare che l'agente recupera l'informazione dall'archivio anziché dalla cronologia delle conversazioni:
azd ai agent invoke --local --new-session "Do you remember my name and any dietary preference I told you earlier?"L'agente risponde con il nome e la preferenza dell'utente, a dimostrazione del fatto che tali informazioni sono state recuperate dall'archivio di memoria.
Passaggio 5. Eseguire la distribuzione in Servizio Agente Fonderia
Distribuire il codice sorgente dell'agente.
azd crea un pacchetto dell'origine come file ZIP e lo carica in Foundry, che risolve le dipendenze e compila l'agente ospitato in modalità remota. L'hook postprovision scrive già MEMORY_STORE_NAME in azure.yaml, quindi l'agente distribuito legge dallo stesso archivio dati:
azd deploy
Al termine dell'esecuzione del comando, l'output mostra i collegamenti al playground dell'agente e all'endpoint dell'agente. Verifica la memoria tra sessioni diverse nell'agente distribuito. Archiviare un fatto:
azd ai agent invoke --new-session "Hi! My name is Marco and I'm allergic to peanuts. Please remember this about me."
Quindi richiamalo in una nuova sessione:
azd ai agent invoke --new-session "What's my name, and is there any food I should avoid?"
L'agente distribuito risponde con il nome e l'allergia memorizzati.
Passaggio 1: Creare o scegliere un progetto Foundry
Aprire il portale di Foundry e creare un progetto Foundry oppure selezionare un progetto esistente.
Nel progetto distribuire:
- Modello con supporto per la chat,
gpt-5.4-miniad esempio . - Un modello di incorporamento come
text-embedding-3-small.
- Modello con supporto per la chat,
Copia l'endpoint del progetto da Panoramica e i nomi delle distribuzioni da Build>Distribuzioni.
Passaggio 2: Scarica il campione di memoria Foundry
Clonare il repository degli esempi di Foundry:
git clone https://github.com/microsoft-foundry/foundry-samples.git
Creare una cartella di lavoro per gli script di distribuzione. In tale cartella creare un .env file con questi valori:
FOUNDRY_PROJECT_ENDPOINT=<your-project-endpoint>
AZURE_AI_MODEL_DEPLOYMENT_NAME=<your-chat-model-deployment-name>
AZURE_AI_EMBEDDING_MODEL_DEPLOYMENT_NAME=<your-embedding-model-deployment-name>
FOUNDRY_HOSTED_AGENT_NAME=memory-agent
MEMORY_STORE_NAME=agent_framework_memory
FOUNDRY_SAMPLE_PATH=<full-path-to-foundry-samples/samples/python/hosted-agents/agent-framework/responses/13-foundry-memory/src/agent-framework-agent-foundry-memory-responses>
Passaggio 3: Effettuare il provisioning dell'archivio di memoria con Python
Questo script può essere eseguito nuovamente in sicurezza. Viene innanzitutto chiamato get(...) per verificare se l'archivio memoria esiste già. Invoca create(...) solo se lo store non viene trovato.
Creare un file denominato provision_memory_store.py nella stessa cartella di lavoro di .env:
import asyncio
import os
from azure.ai.projects.aio import AIProjectClient
from azure.ai.projects.models import (
MemoryStoreDefaultDefinition,
MemoryStoreDefaultOptions,
)
from azure.core.exceptions import ResourceNotFoundError
from azure.identity.aio import DefaultAzureCredential
from dotenv import load_dotenv
load_dotenv()
async def main() -> None:
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
memory_store_name = os.environ["MEMORY_STORE_NAME"]
chat_model = os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
embedding_model = os.environ["AZURE_AI_EMBEDDING_MODEL_DEPLOYMENT_NAME"]
async with (
DefaultAzureCredential() as credential,
AIProjectClient(
endpoint=endpoint,
credential=credential,
allow_preview=True,
) as project,
):
try:
existing = await project.beta.memory_stores.get(name=memory_store_name)
print(
f"Memory store '{existing.name}' already exists "
f"(id={existing.id}); leaving as-is."
)
return
except ResourceNotFoundError:
pass
definition = MemoryStoreDefaultDefinition(
chat_model=chat_model,
embedding_model=embedding_model,
options=MemoryStoreDefaultOptions(
chat_summary_enabled=False,
user_profile_enabled=True,
user_profile_details=(
"Avoid irrelevant or sensitive data, such as age, "
"financials, precise location, and credentials"
),
),
)
created = await project.beta.memory_stores.create(
name=memory_store_name,
description="Memory store for the hosted-agent memory quickstart",
definition=definition,
)
print(f"Created memory store '{created.name}' (id={created.id}).")
asyncio.run(main())
Eseguire lo script:
python provision_memory_store.py
Passaggio 4: Distribuire l'agente ospitato con Python
Creare un file denominato deploy_memory_agent.py nella stessa cartella di lavoro di .env:
import os
import tempfile
import time
import zipfile
from pathlib import Path
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
AgentEndpointConfig,
CodeConfiguration,
CodeDependencyResolution,
FixedRatioVersionSelectionRule,
HostedAgentDefinition,
ProtocolConfiguration,
ProtocolVersionRecord,
ResponsesProtocolConfiguration,
VersionSelector,
)
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv
load_dotenv()
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model_name = os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
agent_name = os.environ.get("FOUNDRY_HOSTED_AGENT_NAME", "memory-agent")
memory_store_name = os.environ["MEMORY_STORE_NAME"]
sample_path = Path(os.environ["FOUNDRY_SAMPLE_PATH"]).resolve()
def create_code_zip(source_dir: Path) -> Path:
zip_path = Path(tempfile.gettempdir()) / f"{agent_name}.zip"
excluded = {".git", ".venv", "__pycache__", ".env"}
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zip_file:
for path in source_dir.rglob("*"):
if not path.is_file():
continue
if any(part in excluded for part in path.parts):
continue
zip_file.write(path, path.relative_to(source_dir))
return zip_path
def wait_for_active_version(project_client: AIProjectClient, version: str) -> None:
for attempt in range(60):
time.sleep(10)
details = project_client.agents.get_version(
agent_name=agent_name,
agent_version=version,
)
status = details["status"]
print(f"Provisioning status: {status} (attempt {attempt + 1}/60)")
if status == "active":
return
if status == "failed":
raise RuntimeError(f"Hosted agent provisioning failed: {dict(details)}")
raise RuntimeError("Timed out waiting for the hosted agent version to become active.")
code_zip_path = create_code_zip(sample_path)
with (
code_zip_path.open("rb") as code_stream,
DefaultAzureCredential() as credential,
AIProjectClient(
endpoint=endpoint,
credential=credential,
allow_preview=True,
) as project_client,
):
original_agent_endpoint = None
created = None
try:
created = project_client.agents.create_version_from_code(
agent_name=agent_name,
description="Hosted agent with persistent Foundry memory.",
definition=HostedAgentDefinition(
cpu="0.5",
memory="1Gi",
code_configuration=CodeConfiguration(
runtime="python_3_13",
entry_point=["python", "main.py"],
dependency_resolution=CodeDependencyResolution.REMOTE_BUILD,
),
environment_variables={
"FOUNDRY_PROJECT_ENDPOINT": endpoint,
"AZURE_AI_MODEL_DEPLOYMENT_NAME": model_name,
"MEMORY_STORE_NAME": memory_store_name,
},
protocol_versions=[
ProtocolVersionRecord(protocol="responses", version="2.0.0")
],
),
code=code_stream,
)
print(f"Created hosted agent version {created.version}")
wait_for_active_version(project_client, created.version)
original_agent_endpoint = project_client.agents.get(
agent_name=agent_name
).agent_endpoint
project_client.agents.update_details(
agent_name=agent_name,
agent_endpoint=AgentEndpointConfig(
version_selector=VersionSelector(
version_selection_rules=[
FixedRatioVersionSelectionRule(
agent_version=created.version,
traffic_percentage=100,
),
]
),
protocol_configuration=ProtocolConfiguration(
responses=ResponsesProtocolConfiguration()
),
),
)
with project_client.get_openai_client(agent_name=agent_name) as openai_client:
first_response = openai_client.responses.create(
input="Hi! My name is Linda and I'm vegetarian. Please remember that.",
)
print(first_response.output_text)
time.sleep(10)
second_response = openai_client.responses.create(
input=(
"Do you remember my name and any dietary preference I told "
"you earlier?"
),
)
print(second_response.output_text)
finally:
if original_agent_endpoint is not None:
project_client.agents.update_details(
agent_name=agent_name,
agent_endpoint=original_agent_endpoint,
)
if created is not None:
project_client.agents.delete_version(
agent_name=agent_name,
agent_version=created.version,
force=True,
)
Eseguire lo script:
python deploy_memory_agent.py
Questo script carica l'esempio di memoria come nuova versione dell'agente ospitato, punta temporaneamente l'agente ospitato a tale versione, lo richiama due volte come utente connesso e ripristina la configurazione dell'endpoint precedente al termine.
Passaggio 5: Verificare che la memoria sia persistente
La prima chiamata archivia il fatto nell'archivio di memoria. La seconda chiamata richiede l'informazione precedentemente memorizzata in una richiesta separata. Se l'archivio di memoria è configurato correttamente, la risposta deve menzionare lo stesso nome e le preferenze alimentari fornite nella prima richiesta.
Pulire le risorse
Elimina le risorse quando hai finito, per evitare ulteriori addebiti.
Per eliminare l'archivio di memoria, usare .AIProjectClient Eseguire questo script in un ambiente Python in cui sono installati i azure-ai-projects pacchetti e azure-identity , ad esempio eseguire pip install "azure-ai-projects>=2.3.0" azure-identity:
import asyncio
from azure.identity.aio import DefaultAzureCredential
from azure.ai.projects.aio import AIProjectClient
async def delete():
async with (
DefaultAzureCredential() as credential,
AIProjectClient(
endpoint="https://<account>.services.ai.azure.com/api/projects/<project>",
credential=credential,
allow_preview=True,
) as project,
):
await project.beta.memory_stores.delete("agent_framework_memory")
asyncio.run(delete())
Eliminare l'agente e le relative risorse Azure:
Warning
Se l'ambiente corrente azd ha creato il progetto Foundry, azd down elimina definitivamente il gruppo di risorse del progetto e tutti gli elementi in esso contenuti. Se è stato selezionato un progetto esistente durante l'inizializzazione, azd down lascia il progetto, il relativo gruppo di risorse, l'agente ospitato e altre risorse di avvio rapido sul posto. Per eliminare le risorse non più necessarie dal progetto esistente, eliminarle separatamente.
azd down
Per eliminare l'archivio memoria, usare lo stesso modello di script con il nome dell'archivio memoria:
import asyncio
import os
from azure.ai.projects.aio import AIProjectClient
from azure.identity.aio import DefaultAzureCredential
from dotenv import load_dotenv
load_dotenv()
async def delete() -> None:
async with (
DefaultAzureCredential() as credential,
AIProjectClient(
endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
credential=credential,
allow_preview=True,
) as project,
):
await project.beta.memory_stores.delete(os.environ["MEMORY_STORE_NAME"])
asyncio.run(delete())
Se è stato creato un gruppo di risorse o un progetto dedicato per questa guida introduttiva, eliminarlo dal portale di Azure dopo che non è più necessaria la distribuzione della chat, la distribuzione di incorporamento o l'agente ospitato.
Risoluzione dei problemi
| Issue | Soluzione |
|---|---|
L'agente distribuito non ha memoria o MEMORY_STORE_NAME è vuoto |
Controllare che l'hook postprovision sia stato eseguito durante azd provision e che azure.yaml sia MEMORY_STORE_NAME impostato. Esegui nuovamente azd provision per eseguire nuovamente l'hook. |
Le scritture di memoria hanno esito negativo con un 401 errore e l'archivio rimane vuoto |
Conferma che il chiamante disponga già dell'accesso Utente Foundry nell'ambito del progetto Foundry e concedi il ruolo Utente OpenAI di Servizi cognitivi nello stesso ambito alla tua identità e all'identità di runtime dell'agente distribuito. |
azd provision ha esito negativo con un errore di autorizzazione |
Verificare che l'identità disponga dei ruoli di progetto elencati nei prerequisiti. |
project.beta.memory_stores.create(...) non riesce con Authentication to the Azure OpenAI resource failed |
Confermare che l'identità disponga già dell'accesso Foundry User nell'ambito del progetto Foundry e che abbia anche il ruolo Cognitive Services OpenAI User in tale ambito. Assicurarsi anche che AZURE_AI_EMBEDDING_MODEL_DEPLOYMENT_NAME punti a una distribuzione valida del modello di embedding. |
| La distribuzione di Python riesce, ma la seconda chiamata non recupera l’informazione memorizzata | Attendere alcuni secondi prima della seconda chiamata in modo che l'archivio memoria termini l'indicizzazione, quindi eseguire di nuovo lo script. |
| L'agente non ricorda un'informazione che hai condiviso | Attendi qualche secondo dopo aver memorizzato un fatto prima di eseguire una query, in modo che l’archivio completi l’indicizzazione della memoria. |
| L'agente non può leggere o scrivere memorie dopo la distribuzione | Confermare che l'hook postprovision abbia creato l'archivio nello stesso progetto in cui è distribuito l'agente. |
Cosa si è appreso
Questo avvio rapido spiega come:
- È stato creato un archivio di memoria Foundry con la funzionalità del profilo utente.
- È stato distribuito un agente ospitato che legge e scrive nell'archivio tramite
FoundryMemoryProviderusando l'interfaccia della riga di comando per sviluppatori di Azure o l'SDK di Python. - È stato verificato che l'agente ricordi le informazioni dell'utente in sessioni separate, sia localmente con Azure Developer CLI sia in remoto con l'SDK Python dopo la distribuzione.