[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69AV2AV22E3GXDSC5GC80RK":3,"skill-same:01M69AV2AV22E3GXDSC5GC80RK":98},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":44,"repositoryHtmlUrl":45,"repositoryHomepageUrl":6,"ownerHtmlUrl":46,"ownerBlogUrl":47,"ownerDescription":48,"updatedAt":49,"install":50,"resources":63},"01M69AV2AV22E3GXDSC5GC80RK","agent-framework-azure-ai-py",null,"Build Azure AI Foundry agents using the Microsoft Agent Framework Python SDK (agent-framework-azure-ai). Use when creating persistent agents with AzureAIAgentsProvider, using hosted tools (code interpreter, file search, web search), integrating MCP servers, managing conversation threads, or implementing streaming responses. Covers function tools, structured outputs, and multi-tool agents.","microsoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69ATPGBJQAGJHX0G1M5B2CN",48,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,9,32],"agent framework","azure ai","azure","agent framework azure ai py","MCP","python","sdk","web","foundry","2026-11-10 10:12:30",false,"---\nname: agent-framework-azure-ai-py\ndescription: Build Azure AI Foundry agents using the Microsoft Agent Framework Python SDK (agent-framework-azure-ai). Use when creating persistent agents with AzureAIAgentsProvider, using hosted tools (code interpreter, file search, web search), integrating MCP servers, managing conversation threads, or implementing streaming responses. Covers function tools, structured outputs, and multi-tool agents.\nlicense: MIT\nmetadata:\n  author: Microsoft\n  version: \"1.0.0\"\n  package: agent-framework-azure-ai\n---\n\n# Agent Framework Azure Hosted Agents\n\nBuild persistent agents on Azure AI Foundry using the Microsoft Agent Framework Python SDK.\n\n## Architecture\n\n```\nUser Query → AzureAIAgentsProvider → Azure AI Agent Service (Persistent)\n                    ↓\n              Agent.run() \u002F Agent.run_stream()\n                    ↓\n              Tools: Functions | Hosted (Code\u002FSearch\u002FWeb) | MCP\n                    ↓\n              AgentThread (conversation persistence)\n```\n\n## Installation\n\n```bash\n# Full framework (recommended)\npip install agent-framework --pre\n\n# Or Azure-specific package only\npip install agent-framework-azure-ai --pre\n```\n\n> **Compatibility note (current prerelease).** Recent `agent-framework` builds publish on PyPI ship with `Agent` (in `agent_framework`) and `FoundryChatClient` (in `agent_framework.foundry`) as the supported high-level entry points, plus `MCPStreamableHTTPTool` for MCP. **`AzureAIAgentsProvider` and `HostedMCPTool` are documented below but may not be exported in your installed version** — if `from agent_framework.azure import AzureAIAgentsProvider` raises `ImportError`, use the **Foundry Chat Client** pattern lower in this file (verified by LAB 1 in the ZavaShop workshop) together with `MCPStreamableHTTPTool` from the [MCP reference](.\u002Freferences\u002Fmcp.md). API surface is the same: `Agent.run(..., session=session)`, `agent.create_session()`, function-tool list, `async with` lifecycle.\n\n## Environment Variables\n\n```bash\nexport AZURE_AI_PROJECT_ENDPOINT=\"https:\u002F\u002F\u003Cproject>.services.ai.azure.com\u002Fapi\u002Fprojects\u002F\u003Cproject-id>\"  # Required for all auth methods\nexport AZURE_AI_MODEL_DEPLOYMENT_NAME=\"gpt-4o-mini\"  # Required for all auth methods\nexport BING_CONNECTION_ID=\"your-bing-connection-id\"  # For web search\nexport AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production\n\n# Foundry Toolbox (see references\u002Ffoundry-toolbox.md)\nexport FOUNDRY_PROJECT_ENDPOINT=\"https:\u002F\u002F\u003Caccount>.services.ai.azure.com\u002Fapi\u002Fprojects\u002F\u003Cproject-id>\"\nexport FOUNDRY_MODEL=\"gpt-4o-mini\"\nexport FOUNDRY_TOOLBOX_ENDPOINT=\"https:\u002F\u002F\u003Caccount>.services.ai.azure.com\u002Fapi\u002Fprojects\u002F\u003Cproject>\u002Ftoolsets\u002F\u003Cname>\u002Fmcp?api-version=v1\"\n```\n\n## Authentication & Lifecycle\n\n> **? Two rules apply to every code sample below:**\n>\n> 1. **Prefer `DefaultAzureCredential`.** It works locally (Azure CLI \u002F VS Code \u002F Developer CLI) and in Azure (managed identity, workload identity) with no code change. Avoid connection strings, account\u002FAPI keys — they bypass Entra audit and rotation.\n>    - Local dev: `DefaultAzureCredential` works as-is.\n>    - Production: set `AZURE_TOKEN_CREDENTIALS=prod` (or `AZURE_TOKEN_CREDENTIALS=\u003Cspecific_credential>`) to constrain the credential chain to production-safe credentials.\n> 2. **Wrap every client in a context manager** so HTTP transports, sockets, and token caches are released deterministically:\n>    - Sync: `with \u003CClient>(...) as client:`\n>    - Async: `async with \u003CClient>(...) as client:` **and** `async with DefaultAzureCredential() as credential:` (from `azure.identity.aio`)\n>\n> Snippets may abbreviate this setup, but production code should always follow both rules.\n\n```python\nfrom azure.identity.aio import AzureCliCredential, DefaultAzureCredential, ManagedIdentityCredential\n\n# Development\ncredential = AzureCliCredential()\n\n# Production\n# Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=\u003Cspecific_credential>\ncredential = DefaultAzureCredential(require_envvar=True)\n# Or use a specific credential directly in production:\n# See https:\u002F\u002Flearn.microsoft.com\u002Fpython\u002Fapi\u002Foverview\u002Fazure\u002Fidentity-readme?view=azure-python#credential-classes\n# credential = ManagedIdentityCredential()\n```\n\n## Core Workflow\n\n### Basic Agent\n\n```python\nimport asyncio\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"MyAgent\",\n            instructions=\"You are a helpful assistant.\",\n        )\n        \n        result = await agent.run(\"Hello!\")\n        print(result.text)\n\nasyncio.run(main())\n```\n\n### Agent with Function Tools\n\n```python\nfrom typing import Annotated\nfrom pydantic import Field\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\ndef get_weather(\n    location: Annotated[str, Field(description=\"City name to get weather for\")],\n) -> str:\n    \"\"\"Get the current weather for a location.\"\"\"\n    return f\"Weather in {location}: 72°F, sunny\"\n\ndef get_current_time() -> str:\n    \"\"\"Get the current UTC time.\"\"\"\n    from datetime import datetime, timezone\n    return datetime.now(timezone.utc).strftime(\"%Y-%m-%d %H:%M:%S UTC\")\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"WeatherAgent\",\n            instructions=\"You help with weather and time queries.\",\n            tools=[get_weather, get_current_time],  # Pass functions directly\n        )\n        \n        result = await agent.run(\"What's the weather in Seattle?\")\n        print(result.text)\n```\n\n### Agent with Hosted Tools\n\n```python\nfrom agent_framework import (\n    HostedCodeInterpreterTool,\n    HostedFileSearchTool,\n    HostedWebSearchTool,\n)\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"MultiToolAgent\",\n            instructions=\"You can execute code, search files, and search the web.\",\n            tools=[\n                HostedCodeInterpreterTool(),\n                HostedWebSearchTool(name=\"Bing\"),\n            ],\n        )\n        \n        result = await agent.run(\"Calculate the factorial of 20 in Python\")\n        print(result.text)\n```\n\n### Streaming Responses\n\n```python\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"StreamingAgent\",\n            instructions=\"You are a helpful assistant.\",\n        )\n        \n        print(\"Agent: \", end=\"\", flush=True)\n        async for chunk in agent.run_stream(\"Tell me a short story\"):\n            if chunk.text:\n                print(chunk.text, end=\"\", flush=True)\n        print()\n```\n\n### Conversation Threads\n\n```python\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"ChatAgent\",\n            instructions=\"You are a helpful assistant.\",\n            tools=[get_weather],\n        )\n        \n        # Create thread for conversation persistence\n        thread = agent.get_new_thread()\n        \n        # First turn\n        result1 = await agent.run(\"What's the weather in Seattle?\", thread=thread)\n        print(f\"Agent: {result1.text}\")\n        \n        # Second turn - context is maintained\n        result2 = await agent.run(\"What about Portland?\", thread=thread)\n        print(f\"Agent: {result2.text}\")\n        \n        # Save thread ID for later resumption\n        print(f\"Conversation ID: {thread.conversation_id}\")\n```\n\n### Structured Outputs\n\n```python\nfrom pydantic import BaseModel, ConfigDict\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nclass WeatherResponse(BaseModel):\n    model_config = ConfigDict(extra=\"forbid\")\n    \n    location: str\n    temperature: float\n    unit: str\n    conditions: str\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"StructuredAgent\",\n            instructions=\"Provide weather information in structured format.\",\n            response_format=WeatherResponse,\n        )\n        \n        result = await agent.run(\"Weather in Seattle?\")\n        weather = WeatherResponse.model_validate_json(result.text)\n        print(f\"{weather.location}: {weather.temperature}°{weather.unit}\")\n```\n\n## Provider Methods\n\n| Method | Description |\n|--------|-------------|\n| `create_agent()` | Create new agent on Azure AI service |\n| `get_agent(agent_id)` | Retrieve existing agent by ID |\n| `as_agent(sdk_agent)` | Wrap SDK Agent object (no HTTP call) |\n\n## Foundry Chat Client (Alternative Pattern)\n\nFor stateless agent calls without creating a persistent Azure AI agent resource, use `FoundryChatClient` directly with `Agent`:\n\n```python\nfrom agent_framework import Agent\nfrom agent_framework.foundry import FoundryChatClient\nfrom azure.identity import DefaultAzureCredential\n\nasync with Agent(\n    client=FoundryChatClient(\n        project_endpoint=os.environ[\"FOUNDRY_PROJECT_ENDPOINT\"],\n        model=os.environ[\"FOUNDRY_MODEL\"],\n        credential=DefaultAzureCredential(),\n    ),\n    instructions=\"You are a helpful assistant.\",\n    tools=...,\n) as agent:\n    result = await agent.run(\"Hello!\")\n```\n\nSee [references\u002Ffoundry-toolbox.md](references\u002Ffoundry-toolbox.md) for the full comparison with `AzureAIAgentsProvider` and the toolbox-consumption pattern.\n\n## Agent Skills (SDK Skill Abstractions)\n\nThe SDK ships an **Agent Skills** runtime that lets an agent advertise modular capability bundles and load them on demand via progressive disclosure (advertise → load → read resource \u002F run script). Skills can be defined three ways and freely composed:\n\n- **Code-defined** — `InlineSkill` with `@skill.resource` and `@skill.script` decorators.\n- **Class-based** — subclass `ClassSkill` and decorate methods with `@ClassSkill.resource` \u002F `@ClassSkill.script`.\n- **File-based** — `SKILL.md` directories on disk discovered by `FileSkillsSource` \u002F `SkillsProvider.from_paths(...)`; file-based scripts require a `script_runner` (e.g. a subprocess runner).\n\nAttach skills to any `Agent` via `context_providers=[SkillsProvider(...)]`:\n\n```python\nfrom agent_framework import Agent, InlineSkill, SkillFrontmatter, SkillsProvider\nfrom agent_framework.foundry import FoundryChatClient\nfrom azure.identity import AzureCliCredential\n\ndeploy_skill = InlineSkill(\n    frontmatter=SkillFrontmatter(name=\"deployment\", description=\"Deploy app versions.\"),\n    instructions=\"Use the deploy script to ship a version to an environment.\",\n)\n\n@deploy_skill.script\ndef deploy(version: str, environment: str = \"staging\") -> str:\n    return f\"Deployed {version} to {environment}\"\n\nasync with Agent(\n    client=FoundryChatClient(project_endpoint=..., model=..., credential=AzureCliCredential()),\n    instructions=\"You are a deployment assistant.\",\n    context_providers=[SkillsProvider(deploy_skill, require_script_approval=True)],\n) as agent:\n    ...\n```\n\nCompose multiple sources with `AggregatingSkillsSource`, `DeduplicatingSkillsSource`, and `FilteringSkillsSource`. Gate sensitive scripts with `require_script_approval=True` and approve via `request.to_function_approval_response(...)` in the `result.user_input_requests` loop.\n\nSee [references\u002Fskills.md](references\u002Fskills.md) for the full guide (code\u002Fclass\u002Ffile patterns, source composition, approval loop, troubleshooting).\n\n## Agent Memory (Foundry Managed)\n\nAttach a Foundry memory store to any agent via `FoundryMemoryProvider` as a context provider. The provider auto-loads static user-profile memories on first run, searches contextual memories every turn, and writes new memories after each interaction.\n\n```python\nfrom agent_framework import Agent, InMemoryHistoryProvider\nfrom agent_framework.foundry import FoundryChatClient, FoundryMemoryProvider\n\nmemory_provider = FoundryMemoryProvider(\n    project_client=project_client,\n    memory_store_name=memory_store.name,\n    scope=\"user_123\",       # per-user partition; defaults to session_id\n    update_delay=0,         # immediate writes in dev; batch in prod\n)\n\nasync with Agent(\n    client=FoundryChatClient(project_client=project_client),\n    instructions=\"You remember user preferences across sessions.\",\n    context_providers=[memory_provider, InMemoryHistoryProvider(load_messages=False)],\n    default_options={\"store\": False},\n) as agent:\n    ...\n```\n\nMemory stores are created on the project (`project_client.beta.memory_stores.create(...)`) with both a **chat model** and an **embedding model** in the definition. Use a stable `scope` (e.g. user ID) for memories that should follow a user across sessions. On the current prerelease, wire `AIProjectClient(per_call_policies=[IdentityEncodingPolicy()])` where the policy sets `Accept-Encoding: identity`; otherwise `memory_stores.create` \u002F `list` \u002F `search_memories` can fail with `UnicodeDecodeError` on gzipped responses. Use uuid-suffixed store names for demos because delete + immediate same-name create can collide.\n\nA 401 from the memory backend hitting the embedding deployment almost always means the **calling identity** lacks the embedding data action. The `Foundry User` role covers chat completions but NOT embeddings, and `FoundryMemoryProvider.search_memories` runs the embedding call under the caller's token. Grant the calling identity — for local dev that's the signed-in user (`az ad signed-in-user show --query id -o tsv`), for server-side hosting the app's managed identity — three roles: `Cognitive Services OpenAI User` on both the AI account and project scopes, plus `Cognitive Services User` on the account scope. The legacy `properties.agentIdentity.agentIdentityId` path is `null` on newer projects and is NOT the fix; only grant that ServiceIdentity SP the same three roles when `az resource show --ids ...\u002Fprojects\u002F\u003Cproject> --api-version 2025-04-01-preview --query \"properties.agentIdentity.agentIdentityId\" -o tsv` returns a non-empty value.\n\nSee [references\u002Fmemory.md](references\u002Fmemory.md) for full setup, `MemoryStoreDefaultDefinition`\u002F`MemoryStoreDefaultOptions`, scope semantics, and troubleshooting.\n\n## Agent Evaluation & Red-Teaming\n\nThree evaluation surfaces ship with `agent-framework-azure-ai`:\n\n- **`FoundryEvals`** — quality, behaviour, tool-use, and safety evaluators run in the Foundry portal.\n- **`RedTeam`** — adversarial scans (PyRIT-backed) that score an agent's Attack Success Rate.\n- **Self-reflection** — a critique-and-retry loop driven by a `FoundryEvals` score.\n\n```python\nfrom agent_framework import evaluate_agent\nfrom agent_framework.foundry import FoundryChatClient, FoundryEvals, evaluate_traces\n\nchat_client = FoundryChatClient(project_endpoint=..., model=..., credential=AzureCliCredential())\nagent_evals = FoundryEvals(\n    client=chat_client,\n    evaluators=[FoundryEvals.RELEVANCE, FoundryEvals.TOOL_CALL_ACCURACY],\n)\n\n# Dev inner loop: run + evaluate in one call\nresults = await evaluate_agent(agent=agent, queries=[...], evaluators=agent_evals)\n\n# Zero-code-change: score responses or App Insights traces after the fact\nresults = await evaluate_traces(\n    response_ids=[\"resp_abc123\", \"resp_def456\"],\n    evaluators=[FoundryEvals.RELEVANCE, FoundryEvals.GROUNDEDNESS, FoundryEvals.TOOL_CALL_ACCURACY],\n    client=chat_client,\n)\n```\n\nUse `ConversationSplit.{LAST_TURN, FULL}` or `EvalItem.per_turn_items(...)` to slice multi-turn conversations. Use `evaluate_workflow(...)` for multi-agent orchestrations; each result entry exposes `sub_results` per agent. For `evaluate_agent(...)` on `agent-framework 1.0.0rc3`, keep the evaluator list to `FoundryEvals.RELEVANCE` + `FoundryEvals.TOOL_CALL_ACCURACY`: `FoundryEvals.GROUNDEDNESS` currently fails the agent-eval dataset path with `MissingRequiredDataMapping: tool_definitions`. Use groundedness only through direct `FoundryEvals.evaluate([EvalItem(..., context=...)])` \u002F self-reflection flows where you provide `context=` manually. Per-item pass\u002Ffail is on `scores[].passed`; `EvalItemResult.status == \"completed\"` is just run status.\n\nFor adversarial testing, install `azure-ai-evaluation[redteam]`. With azure-ai-evaluation 1.16+, import `RedTeam` from `azure.ai.evaluation.red_team`, pass the Foundry project endpoint URL string directly as `azure_ai_project`, and pass a **sync** `azure.identity.AzureCliCredential` to `RedTeam(...)` even when the agent code uses `azure.identity.aio.AzureCliCredential`. Pin `pyrit==0.11.0` for azure-ai-evaluation 1.16+ (`pyrit==0.9.0` for older evaluation packages). Compose attack strategies with nested lists such as `[AttackStrategy.Base64, AttackStrategy.ROT13]` when `AttackStrategy.Compose(...)` is unavailable. Target **ASR \u003C 5%** before production.\n\nSee [references\u002Fevaluation.md](references\u002Fevaluation.md) for the full evaluator catalog, the `AgentEvalConverter` pattern, multi-turn \u002F workflow \u002F similarity flows, red-team strategy list, and the Reflexion self-reflection loop.\n\n## Hosted Tools Quick Reference\n\n| Tool | Import | Purpose |\n|------|--------|---------|\n| `HostedCodeInterpreterTool` | `from agent_framework import HostedCodeInterpreterTool` | Execute Python code |\n| `HostedFileSearchTool` | `from agent_framework import HostedFileSearchTool` | Search vector stores |\n| `HostedWebSearchTool` | `from agent_framework import HostedWebSearchTool` | Bing web search |\n| `HostedMCPTool` | `from agent_framework import HostedMCPTool` | Service-managed MCP |\n| `MCPStreamableHTTPTool` | `from agent_framework import MCPStreamableHTTPTool` | Client-managed MCP |\n\n## Complete Example\n\n```python\nimport asyncio\nfrom typing import Annotated\nfrom pydantic import BaseModel, Field\nfrom agent_framework import (\n    HostedCodeInterpreterTool,\n    HostedWebSearchTool,\n    MCPStreamableHTTPTool,\n)\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\n\ndef get_weather(\n    location: Annotated[str, Field(description=\"City name\")],\n) -> str:\n    \"\"\"Get weather for a location.\"\"\"\n    return f\"Weather in {location}: 72°F, sunny\"\n\n\nclass AnalysisResult(BaseModel):\n    summary: str\n    key_findings: list[str]\n    confidence: float\n\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        MCPStreamableHTTPTool(\n            name=\"Docs MCP\",\n            url=\"https:\u002F\u002Flearn.microsoft.com\u002Fapi\u002Fmcp\",\n        ) as mcp_tool,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"ResearchAssistant\",\n            instructions=\"You are a research assistant with multiple capabilities.\",\n            tools=[\n                get_weather,\n                HostedCodeInterpreterTool(),\n                HostedWebSearchTool(name=\"Bing\"),\n                mcp_tool,\n            ],\n        )\n        \n        thread = agent.get_new_thread()\n        \n        # Non-streaming\n        result = await agent.run(\n            \"Search for Python best practices and summarize\",\n            thread=thread,\n        )\n        print(f\"Response: {result.text}\")\n        \n        # Streaming\n        print(\"\\nStreaming: \", end=\"\")\n        async for chunk in agent.run_stream(\"Continue with examples\", thread=thread):\n            if chunk.text:\n                print(chunk.text, end=\"\", flush=True)\n        print()\n        \n        # Structured output\n        result = await agent.run(\n            \"Analyze findings\",\n            thread=thread,\n            response_format=AnalysisResult,\n        )\n        analysis = AnalysisResult.model_validate_json(result.text)\n        print(f\"\\nConfidence: {analysis.confidence}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Conventions\n\n- Always use async context managers: `async with provider:`\n- Pass functions directly to `tools=` parameter (auto-converted to AIFunction)\n- Use `Annotated[type, Field(description=...)]` for function parameters\n- Use `get_new_thread()` for multi-turn conversations\n- Prefer `HostedMCPTool` for service-managed MCP, `MCPStreamableHTTPTool` for client-managed\n\n## Best Practices\n\n1. **This SDK is async-first** — use `async def` handlers and `async with` throughout.\n2. **Always use context managers for clients and async credentials.** Wrap every client in `with Client(...) as client:` (sync) or `async with Client(...) as client:` (async). For async `DefaultAzureCredential` from `azure.identity.aio`, also use `async with credential:` so tokens and transports are cleaned up.\n\n## Reference Files\n\n- [references\u002Ftools.md](references\u002Ftools.md): Detailed hosted tool patterns\n- [references\u002Fmcp.md](references\u002Fmcp.md): MCP integration (hosted + local)\n- [references\u002Ffoundry-toolbox.md](references\u002Ffoundry-toolbox.md): Foundry Toolbox + `FoundryChatClient` + `header_provider` patterns\n- [references\u002Fskills.md](references\u002Fskills.md): Agent Skills (code\u002Fclass\u002Ffile), source composition, script approval, filtering\n- [references\u002Fmemory.md](references\u002Fmemory.md): `FoundryMemoryProvider`, memory stores, scope semantics, chat-history coexistence\n- [references\u002Fevaluation.md](references\u002Fevaluation.md): `FoundryEvals`, `evaluate_agent` \u002F `evaluate_traces` \u002F `evaluate_workflow`, multi-turn splits, red-teaming, self-reflection loop\n- [references\u002Fthreads.md](references\u002Fthreads.md): Thread and conversation management\n- [references\u002Fadvanced.md](references\u002Fadvanced.md): OpenAPI, citations, structured outputs\n","# Agent Framework Azure Hosted Agents\n\nBuild persistent agents on Azure AI Foundry using the Microsoft Agent Framework Python SDK.\n\n## Architecture\n\n```\nUser Query → AzureAIAgentsProvider → Azure AI Agent Service (Persistent)\n                    ↓\n              Agent.run() \u002F Agent.run_stream()\n                    ↓\n              Tools: Functions | Hosted (Code\u002FSearch\u002FWeb) | MCP\n                    ↓\n              AgentThread (conversation persistence)\n```\n\n## Installation\n\n```bash\n# Full framework (recommended)\npip install agent-framework --pre\n\n# Or Azure-specific package only\npip install agent-framework-azure-ai --pre\n```\n\n> **Compatibility note (current prerelease).** Recent `agent-framework` builds publish on PyPI ship with `Agent` (in `agent_framework`) and `FoundryChatClient` (in `agent_framework.foundry`) as the supported high-level entry points, plus `MCPStreamableHTTPTool` for MCP. **`AzureAIAgentsProvider` and `HostedMCPTool` are documented below but may not be exported in your installed version** — if `from agent_framework.azure import AzureAIAgentsProvider` raises `ImportError`, use the **Foundry Chat Client** pattern lower in this file (verified by LAB 1 in the ZavaShop workshop) together with `MCPStreamableHTTPTool` from the [MCP reference](.\u002Freferences\u002Fmcp.md). API surface is the same: `Agent.run(..., session=session)`, `agent.create_session()`, function-tool list, `async with` lifecycle.\n\n## Environment Variables\n\n```bash\nexport AZURE_AI_PROJECT_ENDPOINT=\"https:\u002F\u002F\u003Cproject>.services.ai.azure.com\u002Fapi\u002Fprojects\u002F\u003Cproject-id>\"  # Required for all auth methods\nexport AZURE_AI_MODEL_DEPLOYMENT_NAME=\"gpt-4o-mini\"  # Required for all auth methods\nexport BING_CONNECTION_ID=\"your-bing-connection-id\"  # For web search\nexport AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production\n\n# Foundry Toolbox (see references\u002Ffoundry-toolbox.md)\nexport FOUNDRY_PROJECT_ENDPOINT=\"https:\u002F\u002F\u003Caccount>.services.ai.azure.com\u002Fapi\u002Fprojects\u002F\u003Cproject-id>\"\nexport FOUNDRY_MODEL=\"gpt-4o-mini\"\nexport FOUNDRY_TOOLBOX_ENDPOINT=\"https:\u002F\u002F\u003Caccount>.services.ai.azure.com\u002Fapi\u002Fprojects\u002F\u003Cproject>\u002Ftoolsets\u002F\u003Cname>\u002Fmcp?api-version=v1\"\n```\n\n## Authentication & Lifecycle\n\n> **? Two rules apply to every code sample below:**\n>\n> 1. **Prefer `DefaultAzureCredential`.** It works locally (Azure CLI \u002F VS Code \u002F Developer CLI) and in Azure (managed identity, workload identity) with no code change. Avoid connection strings, account\u002FAPI keys — they bypass Entra audit and rotation.\n>    - Local dev: `DefaultAzureCredential` works as-is.\n>    - Production: set `AZURE_TOKEN_CREDENTIALS=prod` (or `AZURE_TOKEN_CREDENTIALS=\u003Cspecific_credential>`) to constrain the credential chain to production-safe credentials.\n> 2. **Wrap every client in a context manager** so HTTP transports, sockets, and token caches are released deterministically:\n>    - Sync: `with \u003CClient>(...) as client:`\n>    - Async: `async with \u003CClient>(...) as client:` **and** `async with DefaultAzureCredential() as credential:` (from `azure.identity.aio`)\n>\n> Snippets may abbreviate this setup, but production code should always follow both rules.\n\n```python\nfrom azure.identity.aio import AzureCliCredential, DefaultAzureCredential, ManagedIdentityCredential\n\n# Development\ncredential = AzureCliCredential()\n\n# Production\n# Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=\u003Cspecific_credential>\ncredential = DefaultAzureCredential(require_envvar=True)\n# Or use a specific credential directly in production:\n# See https:\u002F\u002Flearn.microsoft.com\u002Fpython\u002Fapi\u002Foverview\u002Fazure\u002Fidentity-readme?view=azure-python#credential-classes\n# credential = ManagedIdentityCredential()\n```\n\n## Core Workflow\n\n### Basic Agent\n\n```python\nimport asyncio\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"MyAgent\",\n            instructions=\"You are a helpful assistant.\",\n        )\n        \n        result = await agent.run(\"Hello!\")\n        print(result.text)\n\nasyncio.run(main())\n```\n\n### Agent with Function Tools\n\n```python\nfrom typing import Annotated\nfrom pydantic import Field\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\ndef get_weather(\n    location: Annotated[str, Field(description=\"City name to get weather for\")],\n) -> str:\n    \"\"\"Get the current weather for a location.\"\"\"\n    return f\"Weather in {location}: 72°F, sunny\"\n\ndef get_current_time() -> str:\n    \"\"\"Get the current UTC time.\"\"\"\n    from datetime import datetime, timezone\n    return datetime.now(timezone.utc).strftime(\"%Y-%m-%d %H:%M:%S UTC\")\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"WeatherAgent\",\n            instructions=\"You help with weather and time queries.\",\n            tools=[get_weather, get_current_time],  # Pass functions directly\n        )\n        \n        result = await agent.run(\"What's the weather in Seattle?\")\n        print(result.text)\n```\n\n### Agent with Hosted Tools\n\n```python\nfrom agent_framework import (\n    HostedCodeInterpreterTool,\n    HostedFileSearchTool,\n    HostedWebSearchTool,\n)\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"MultiToolAgent\",\n            instructions=\"You can execute code, search files, and search the web.\",\n            tools=[\n                HostedCodeInterpreterTool(),\n                HostedWebSearchTool(name=\"Bing\"),\n            ],\n        )\n        \n        result = await agent.run(\"Calculate the factorial of 20 in Python\")\n        print(result.text)\n```\n\n### Streaming Responses\n\n```python\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"StreamingAgent\",\n            instructions=\"You are a helpful assistant.\",\n        )\n        \n        print(\"Agent: \", end=\"\", flush=True)\n        async for chunk in agent.run_stream(\"Tell me a short story\"):\n            if chunk.text:\n                print(chunk.text, end=\"\", flush=True)\n        print()\n```\n\n### Conversation Threads\n\n```python\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"ChatAgent\",\n            instructions=\"You are a helpful assistant.\",\n            tools=[get_weather],\n        )\n        \n        # Create thread for conversation persistence\n        thread = agent.get_new_thread()\n        \n        # First turn\n        result1 = await agent.run(\"What's the weather in Seattle?\", thread=thread)\n        print(f\"Agent: {result1.text}\")\n        \n        # Second turn - context is maintained\n        result2 = await agent.run(\"What about Portland?\", thread=thread)\n        print(f\"Agent: {result2.text}\")\n        \n        # Save thread ID for later resumption\n        print(f\"Conversation ID: {thread.conversation_id}\")\n```\n\n### Structured Outputs\n\n```python\nfrom pydantic import BaseModel, ConfigDict\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\nclass WeatherResponse(BaseModel):\n    model_config = ConfigDict(extra=\"forbid\")\n    \n    location: str\n    temperature: float\n    unit: str\n    conditions: str\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"StructuredAgent\",\n            instructions=\"Provide weather information in structured format.\",\n            response_format=WeatherResponse,\n        )\n        \n        result = await agent.run(\"Weather in Seattle?\")\n        weather = WeatherResponse.model_validate_json(result.text)\n        print(f\"{weather.location}: {weather.temperature}°{weather.unit}\")\n```\n\n## Provider Methods\n\n| Method | Description |\n|--------|-------------|\n| `create_agent()` | Create new agent on Azure AI service |\n| `get_agent(agent_id)` | Retrieve existing agent by ID |\n| `as_agent(sdk_agent)` | Wrap SDK Agent object (no HTTP call) |\n\n## Foundry Chat Client (Alternative Pattern)\n\nFor stateless agent calls without creating a persistent Azure AI agent resource, use `FoundryChatClient` directly with `Agent`:\n\n```python\nfrom agent_framework import Agent\nfrom agent_framework.foundry import FoundryChatClient\nfrom azure.identity import DefaultAzureCredential\n\nasync with Agent(\n    client=FoundryChatClient(\n        project_endpoint=os.environ[\"FOUNDRY_PROJECT_ENDPOINT\"],\n        model=os.environ[\"FOUNDRY_MODEL\"],\n        credential=DefaultAzureCredential(),\n    ),\n    instructions=\"You are a helpful assistant.\",\n    tools=...,\n) as agent:\n    result = await agent.run(\"Hello!\")\n```\n\nSee [references\u002Ffoundry-toolbox.md](references\u002Ffoundry-toolbox.md) for the full comparison with `AzureAIAgentsProvider` and the toolbox-consumption pattern.\n\n## Agent Skills (SDK Skill Abstractions)\n\nThe SDK ships an **Agent Skills** runtime that lets an agent advertise modular capability bundles and load them on demand via progressive disclosure (advertise → load → read resource \u002F run script). Skills can be defined three ways and freely composed:\n\n- **Code-defined** — `InlineSkill` with `@skill.resource` and `@skill.script` decorators.\n- **Class-based** — subclass `ClassSkill` and decorate methods with `@ClassSkill.resource` \u002F `@ClassSkill.script`.\n- **File-based** — `SKILL.md` directories on disk discovered by `FileSkillsSource` \u002F `SkillsProvider.from_paths(...)`; file-based scripts require a `script_runner` (e.g. a subprocess runner).\n\nAttach skills to any `Agent` via `context_providers=[SkillsProvider(...)]`:\n\n```python\nfrom agent_framework import Agent, InlineSkill, SkillFrontmatter, SkillsProvider\nfrom agent_framework.foundry import FoundryChatClient\nfrom azure.identity import AzureCliCredential\n\ndeploy_skill = InlineSkill(\n    frontmatter=SkillFrontmatter(name=\"deployment\", description=\"Deploy app versions.\"),\n    instructions=\"Use the deploy script to ship a version to an environment.\",\n)\n\n@deploy_skill.script\ndef deploy(version: str, environment: str = \"staging\") -> str:\n    return f\"Deployed {version} to {environment}\"\n\nasync with Agent(\n    client=FoundryChatClient(project_endpoint=..., model=..., credential=AzureCliCredential()),\n    instructions=\"You are a deployment assistant.\",\n    context_providers=[SkillsProvider(deploy_skill, require_script_approval=True)],\n) as agent:\n    ...\n```\n\nCompose multiple sources with `AggregatingSkillsSource`, `DeduplicatingSkillsSource`, and `FilteringSkillsSource`. Gate sensitive scripts with `require_script_approval=True` and approve via `request.to_function_approval_response(...)` in the `result.user_input_requests` loop.\n\nSee [references\u002Fskills.md](references\u002Fskills.md) for the full guide (code\u002Fclass\u002Ffile patterns, source composition, approval loop, troubleshooting).\n\n## Agent Memory (Foundry Managed)\n\nAttach a Foundry memory store to any agent via `FoundryMemoryProvider` as a context provider. The provider auto-loads static user-profile memories on first run, searches contextual memories every turn, and writes new memories after each interaction.\n\n```python\nfrom agent_framework import Agent, InMemoryHistoryProvider\nfrom agent_framework.foundry import FoundryChatClient, FoundryMemoryProvider\n\nmemory_provider = FoundryMemoryProvider(\n    project_client=project_client,\n    memory_store_name=memory_store.name,\n    scope=\"user_123\",       # per-user partition; defaults to session_id\n    update_delay=0,         # immediate writes in dev; batch in prod\n)\n\nasync with Agent(\n    client=FoundryChatClient(project_client=project_client),\n    instructions=\"You remember user preferences across sessions.\",\n    context_providers=[memory_provider, InMemoryHistoryProvider(load_messages=False)],\n    default_options={\"store\": False},\n) as agent:\n    ...\n```\n\nMemory stores are created on the project (`project_client.beta.memory_stores.create(...)`) with both a **chat model** and an **embedding model** in the definition. Use a stable `scope` (e.g. user ID) for memories that should follow a user across sessions. On the current prerelease, wire `AIProjectClient(per_call_policies=[IdentityEncodingPolicy()])` where the policy sets `Accept-Encoding: identity`; otherwise `memory_stores.create` \u002F `list` \u002F `search_memories` can fail with `UnicodeDecodeError` on gzipped responses. Use uuid-suffixed store names for demos because delete + immediate same-name create can collide.\n\nA 401 from the memory backend hitting the embedding deployment almost always means the **calling identity** lacks the embedding data action. The `Foundry User` role covers chat completions but NOT embeddings, and `FoundryMemoryProvider.search_memories` runs the embedding call under the caller's token. Grant the calling identity — for local dev that's the signed-in user (`az ad signed-in-user show --query id -o tsv`), for server-side hosting the app's managed identity — three roles: `Cognitive Services OpenAI User` on both the AI account and project scopes, plus `Cognitive Services User` on the account scope. The legacy `properties.agentIdentity.agentIdentityId` path is `null` on newer projects and is NOT the fix; only grant that ServiceIdentity SP the same three roles when `az resource show --ids ...\u002Fprojects\u002F\u003Cproject> --api-version 2025-04-01-preview --query \"properties.agentIdentity.agentIdentityId\" -o tsv` returns a non-empty value.\n\nSee [references\u002Fmemory.md](references\u002Fmemory.md) for full setup, `MemoryStoreDefaultDefinition`\u002F`MemoryStoreDefaultOptions`, scope semantics, and troubleshooting.\n\n## Agent Evaluation & Red-Teaming\n\nThree evaluation surfaces ship with `agent-framework-azure-ai`:\n\n- **`FoundryEvals`** — quality, behaviour, tool-use, and safety evaluators run in the Foundry portal.\n- **`RedTeam`** — adversarial scans (PyRIT-backed) that score an agent's Attack Success Rate.\n- **Self-reflection** — a critique-and-retry loop driven by a `FoundryEvals` score.\n\n```python\nfrom agent_framework import evaluate_agent\nfrom agent_framework.foundry import FoundryChatClient, FoundryEvals, evaluate_traces\n\nchat_client = FoundryChatClient(project_endpoint=..., model=..., credential=AzureCliCredential())\nagent_evals = FoundryEvals(\n    client=chat_client,\n    evaluators=[FoundryEvals.RELEVANCE, FoundryEvals.TOOL_CALL_ACCURACY],\n)\n\n# Dev inner loop: run + evaluate in one call\nresults = await evaluate_agent(agent=agent, queries=[...], evaluators=agent_evals)\n\n# Zero-code-change: score responses or App Insights traces after the fact\nresults = await evaluate_traces(\n    response_ids=[\"resp_abc123\", \"resp_def456\"],\n    evaluators=[FoundryEvals.RELEVANCE, FoundryEvals.GROUNDEDNESS, FoundryEvals.TOOL_CALL_ACCURACY],\n    client=chat_client,\n)\n```\n\nUse `ConversationSplit.{LAST_TURN, FULL}` or `EvalItem.per_turn_items(...)` to slice multi-turn conversations. Use `evaluate_workflow(...)` for multi-agent orchestrations; each result entry exposes `sub_results` per agent. For `evaluate_agent(...)` on `agent-framework 1.0.0rc3`, keep the evaluator list to `FoundryEvals.RELEVANCE` + `FoundryEvals.TOOL_CALL_ACCURACY`: `FoundryEvals.GROUNDEDNESS` currently fails the agent-eval dataset path with `MissingRequiredDataMapping: tool_definitions`. Use groundedness only through direct `FoundryEvals.evaluate([EvalItem(..., context=...)])` \u002F self-reflection flows where you provide `context=` manually. Per-item pass\u002Ffail is on `scores[].passed`; `EvalItemResult.status == \"completed\"` is just run status.\n\nFor adversarial testing, install `azure-ai-evaluation[redteam]`. With azure-ai-evaluation 1.16+, import `RedTeam` from `azure.ai.evaluation.red_team`, pass the Foundry project endpoint URL string directly as `azure_ai_project`, and pass a **sync** `azure.identity.AzureCliCredential` to `RedTeam(...)` even when the agent code uses `azure.identity.aio.AzureCliCredential`. Pin `pyrit==0.11.0` for azure-ai-evaluation 1.16+ (`pyrit==0.9.0` for older evaluation packages). Compose attack strategies with nested lists such as `[AttackStrategy.Base64, AttackStrategy.ROT13]` when `AttackStrategy.Compose(...)` is unavailable. Target **ASR \u003C 5%** before production.\n\nSee [references\u002Fevaluation.md](references\u002Fevaluation.md) for the full evaluator catalog, the `AgentEvalConverter` pattern, multi-turn \u002F workflow \u002F similarity flows, red-team strategy list, and the Reflexion self-reflection loop.\n\n## Hosted Tools Quick Reference\n\n| Tool | Import | Purpose |\n|------|--------|---------|\n| `HostedCodeInterpreterTool` | `from agent_framework import HostedCodeInterpreterTool` | Execute Python code |\n| `HostedFileSearchTool` | `from agent_framework import HostedFileSearchTool` | Search vector stores |\n| `HostedWebSearchTool` | `from agent_framework import HostedWebSearchTool` | Bing web search |\n| `HostedMCPTool` | `from agent_framework import HostedMCPTool` | Service-managed MCP |\n| `MCPStreamableHTTPTool` | `from agent_framework import MCPStreamableHTTPTool` | Client-managed MCP |\n\n## Complete Example\n\n```python\nimport asyncio\nfrom typing import Annotated\nfrom pydantic import BaseModel, Field\nfrom agent_framework import (\n    HostedCodeInterpreterTool,\n    HostedWebSearchTool,\n    MCPStreamableHTTPTool,\n)\nfrom agent_framework.azure import AzureAIAgentsProvider\nfrom azure.identity.aio import AzureCliCredential\n\n\ndef get_weather(\n    location: Annotated[str, Field(description=\"City name\")],\n) -> str:\n    \"\"\"Get weather for a location.\"\"\"\n    return f\"Weather in {location}: 72°F, sunny\"\n\n\nclass AnalysisResult(BaseModel):\n    summary: str\n    key_findings: list[str]\n    confidence: float\n\n\nasync def main():\n    async with (\n        AzureCliCredential() as credential,\n        MCPStreamableHTTPTool(\n            name=\"Docs MCP\",\n            url=\"https:\u002F\u002Flearn.microsoft.com\u002Fapi\u002Fmcp\",\n        ) as mcp_tool,\n        AzureAIAgentsProvider(credential=credential) as provider,\n    ):\n        agent = await provider.create_agent(\n            name=\"ResearchAssistant\",\n            instructions=\"You are a research assistant with multiple capabilities.\",\n            tools=[\n                get_weather,\n                HostedCodeInterpreterTool(),\n                HostedWebSearchTool(name=\"Bing\"),\n                mcp_tool,\n            ],\n        )\n        \n        thread = agent.get_new_thread()\n        \n        # Non-streaming\n        result = await agent.run(\n            \"Search for Python best practices and summarize\",\n            thread=thread,\n        )\n        print(f\"Response: {result.text}\")\n        \n        # Streaming\n        print(\"\\nStreaming: \", end=\"\")\n        async for chunk in agent.run_stream(\"Continue with examples\", thread=thread):\n            if chunk.text:\n                print(chunk.text, end=\"\", flush=True)\n        print()\n        \n        # Structured output\n        result = await agent.run(\n            \"Analyze findings\",\n            thread=thread,\n            response_format=AnalysisResult,\n        )\n        analysis = AnalysisResult.model_validate_json(result.text)\n        print(f\"\\nConfidence: {analysis.confidence}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Conventions\n\n- Always use async context managers: `async with provider:`\n- Pass functions directly to `tools=` parameter (auto-converted to AIFunction)\n- Use `Annotated[type, Field(description=...)]` for function parameters\n- Use `get_new_thread()` for multi-turn conversations\n- Prefer `HostedMCPTool` for service-managed MCP, `MCPStreamableHTTPTool` for client-managed\n\n## Best Practices\n\n1. **This SDK is async-first** — use `async def` handlers and `async with` throughout.\n2. **Always use context managers for clients and async credentials.** Wrap every client in `with Client(...) as client:` (sync) or `async with Client(...) as client:` (async). For async `DefaultAzureCredential` from `azure.identity.aio`, also use `async with credential:` so tokens and transports are cleaned up.\n\n## Reference Files\n\n- [references\u002Ftools.md](references\u002Ftools.md): Detailed hosted tool patterns\n- [references\u002Fmcp.md](references\u002Fmcp.md): MCP integration (hosted + local)\n- [references\u002Ffoundry-toolbox.md](references\u002Ffoundry-toolbox.md): Foundry Toolbox + `FoundryChatClient` + `header_provider` patterns\n- [references\u002Fskills.md](references\u002Fskills.md): Agent Skills (code\u002Fclass\u002Ffile), source composition, script approval, filtering\n- [references\u002Fmemory.md](references\u002Fmemory.md): `FoundryMemoryProvider`, memory stores, scope semantics, chat-history coexistence\n- [references\u002Fevaluation.md](references\u002Fevaluation.md): `FoundryEvals`, `evaluate_agent` \u002F `evaluate_traces` \u002F `evaluate_workflow`, multi-turn splits, red-teaming, self-reflection loop\n- [references\u002Fthreads.md](references\u002Fthreads.md): Thread and conversation management\n- [references\u002Fadvanced.md](references\u002Fadvanced.md): OpenAPI, citations, structured outputs\n",{"name":5,"license":15,"metadata":38,"description":7},{"author":12,"package":39,"version":40},"agent-framework-azure-ai","1.0.0","main","586d2a6053b9ed89e357a3fd26204b1efd6f593c",".github\u002Fskills\u002Fagent-framework-azure-ai-py",25,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-05-27 15:18:36",{"source":8,"skillName":5,"commands":51,"prompt":61,"zipAvailable":62},[52,55,58],{"tool":53,"command":54},"npx","npx skills add microsoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop --skill agent-framework-azure-ai-py",{"tool":56,"command":57},"bunx","bunx skills add microsoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop --skill agent-framework-azure-ai-py",{"tool":59,"command":60},"pnpm","pnpm dlx skills add microsoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop --skill agent-framework-azure-ai-py","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002FSKILL.md",true,[64,70,74,78,82,86,90,94],{"path":65,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":68,"sourceHtmlUrl":69},"references\u002Fadvanced.md","REFERENCE","参考文档",13356,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Fadvanced.md",{"path":71,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":72,"sourceHtmlUrl":73},"references\u002Fevaluation.md",21546,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Fevaluation.md",{"path":75,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":76,"sourceHtmlUrl":77},"references\u002Ffoundry-toolbox.md",8812,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Ffoundry-toolbox.md",{"path":79,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Fmcp.md",8333,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Fmcp.md",{"path":83,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":84,"sourceHtmlUrl":85},"references\u002Fmemory.md",14031,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Fmemory.md",{"path":87,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":88,"sourceHtmlUrl":89},"references\u002Fskills.md",20421,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Fskills.md",{"path":91,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":92,"sourceHtmlUrl":93},"references\u002Fthreads.md",9484,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Fthreads.md",{"path":95,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":96,"sourceHtmlUrl":97},"references\u002Ftools.md",7468,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-py\u002Freferences\u002Ftools.md",[99,111,127,142,158],{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":106,"publishedAt":33},"01M69AV8BVRD34GACS40NB3NS0","agent-framework-workflows-py","Build deterministic multi-step, multi-agent workflows in Python with the Microsoft Agent Framework (`agent-framework`). Use when composing `Executor` nodes and edges, embedding `Agent` instances as workflow nodes, streaming workflow events, fan-out\u002Ffan-in, conditional routing, loops, checkpointing and resume, human-in-the-loop with `ctx.request_info()`, sub-workflows with `WorkflowExecutor`, wrapping a workflow as an agent with `workflow.as_agent()`, or using the high-level orchestration builders (`SequentialBuilder`, `ConcurrentBuilder`, `HandoffBuilder`, `GroupChatBuilder`, `MagenticBuilder`).","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-workflows-py\u002FSKILL.md",[105],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[24,107,108,29,109,110,9],"workflows","agent framework workflows py","orchestration","workflow",{"skillNo":112,"name":113,"nameZh":6,"description":114,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":123,"publishedAt":33},"01M69AV5QEKJXJ66BP6GZ83ZYE","agent-framework-workflows-csharp","Build deterministic, multi-step workflows with the Microsoft Agent Framework .NET SDK (Microsoft.Agents.AI.Workflows). Use when composing executors and edges into a DAG, running agents as graph nodes, doing fan-out\u002Ffan-in concurrency, conditional routing, shared state, streaming events, checkpoint\u002Fresume, human-in-the-loop request ports, or higher-level orchestration patterns (sequential, concurrent, handoff, group chat, Magentic). Covers WorkflowBuilder, AgentWorkflowBuilder, IWorkflowContext, CheckpointManager, and the StreamingRun event loop.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-workflows-csharp\u002FSKILL.md",[117,118],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":119,"categoryName":120,"taxonomyType":121,"taxonomyTypeDesc":122},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[107,24,124,9,109,125,30,126],"agent framework workflows csharp","dag","handoff",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":137,"publishedAt":33},"01M69ATZ0523NG0E1EJ1AFE6N4","agent-framework-azure-ai-csharp","Build Microsoft Foundry agents with the Microsoft Agent Framework .NET SDK (Microsoft.Agents.AI + Microsoft.Agents.AI.Foundry). Use when creating agents via AIProjectClient.AsAIAgent or FoundryAgent, calling function tools and hosted tools (code interpreter, file search, web search, memory search), integrating MCP servers (local McpClient and hosted ResponseTool.CreateMcpTool), consuming Foundry Toolboxes via MCP, managing AgentSession multi-turn conversations, producing structured output with ChatResponseFormat.ForJsonSchema, attaching FoundryMemoryProvider, or shipping reusable AgentInlineSkill \u002F AgentClassSkill bundles via AgentSkillsProvider.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-azure-ai-csharp\u002FSKILL.md",[133,134],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":135,"categoryName":136,"taxonomyType":121,"taxonomyTypeDesc":122},"01JBSEEDCAT000000000000030","开发工程师",[26,25,24,138,139,140,28,30,141,31,9,32],"agent framework azure ai csharp","microsoft foundry","foundry toolboxes","memory",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":155,"publishedAt":33},"01M69ATW1JPFQZV0R6GGGZQTT7","agent-framework-agui-py","Build AG-UI (Agent UI) protocol servers and clients in Python with the Microsoft Agent Framework (`agent-framework-ag-ui`). Use when hosting an `Agent` or `Workflow` as a streaming HTTP endpoint via `add_agent_framework_fastapi_endpoint`, consuming an AG-UI server with `AGUIChatClient`, wiring hybrid client-side + server-side tool calls, managing thread-scoped state and conversation continuity, returning rich tool payloads via `state_update`, or implementing the seven standard AG-UI features (chat, backend tool rendering, human-in-the-loop, generative UI, tool-based UI, shared state, predictive state updates).","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-agui-py\u002FSKILL.md",[148,151,152],{"categoryNo":149,"categoryName":150,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":153,"categoryName":154,"taxonomyType":121,"taxonomyTypeDesc":122},"01JBSEEDCAT000000000000032","设计师",[156,24,157,29,110,9],"agent framework agui py","http",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":170,"publishedAt":33},"01M69ATRJ4YQH0KVP7ZE6Z1VN5","agent-framework-agui-csharp","Build AG-UI protocol clients and servers with the Microsoft Agent Framework .NET SDK (Microsoft.Agents.AI.AGUI + Microsoft.Agents.AI.Hosting.AGUI.AspNetCore). Use when exposing an AIAgent over HTTP with server-sent events, building remote agent clients, supporting frontend tool rendering, agentic generative UI, predictive state updates, shared state, or human-in-the-loop UX. Covers AGUIChatClient, MapAGUI, AddAGUI, session storage, DelegatingAIAgent, and the AgentResponseUpdate streaming contract.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FLearn-Microsoft-Agent-Framework-with-Foundry-ZavaShop-Supply-Chain-Workshop\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagent-framework-agui-csharp\u002FSKILL.md",[164,167,168,169],{"categoryNo":165,"categoryName":166,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":149,"categoryName":150,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":153,"categoryName":154,"taxonomyType":121,"taxonomyTypeDesc":122},[171,24,172,30,173,9,157,174],"agent framework agui csharp","agentic","storage","frontend"]