Principle:Microsoft Agent framework YAML Agent Loading
| Knowledge Sources | |
|---|---|
| Domains | Declarative_Systems, Agent_Architecture |
| Last Updated | 2026-02-11 00:00 GMT |
Overview
A declarative loading pattern that converts YAML agent definitions into fully configured Agent instances identical to those created programmatically. The AgentFactory class is the entry point for this pattern, accepting a YAML document (as a string or file path), validating it against the agent schema, resolving the model provider, constructing the appropriate chat client, binding tools, and returning a standard Agent object ready for execution.
Description
The YAML Agent Loading principle establishes a configuration-as-code approach to agent construction. Instead of writing Python code to manually instantiate a chat client, configure tools, and compose an Agent, developers author a declarative YAML document that describes the desired agent. The AgentFactory then interprets this document and performs the equivalent construction steps automatically.
The loading pipeline proceeds through a well-defined sequence of stages:
- YAML Parsing: The raw YAML string is parsed using
yaml.safe_load()into a Python dictionary. This stage handles both inline YAML strings and file-based definitions. - Schema Validation and Dispatch: The dictionary is passed through
agent_schema_dispatch(), which inspects thekindfield and instantiates the corresponding model class. For agent creation, onlykind: Prompt(mapped to thePromptAgentmodel) is supported. Any other kind raises aDeclarativeLoaderError. - Provider Resolution: The factory resolves the model provider using the
model.providerand optionalmodel.apiTypefields. These are combined into a lookup key (e.g.,"OpenAI.Chat","AzureOpenAI.Responses") and matched against an internal provider type mapping dictionary. The mapping specifies the Python package, class name, and constructor parameter name for each supported provider. Custom providers can be registered via theadditional_mappingsconstructor argument. - Chat Client Construction: Using the resolved provider mapping, the factory dynamically imports the appropriate module and instantiates the chat client class. Connection parameters (API keys, endpoints, references) are extracted from the YAML
model.connectionblock and injected into the client constructor. If a pre-configured client was supplied to the factory, it is used instead of creating a new one. - Tool Binding: The
toolslist from the YAML is parsed into framework-compatible tool objects. Function tools are matched against thebindingsdictionary provided to the factory constructor, linking YAML tool declarations to actual Python callables. Additional tool types (web search, file search, code interpreter, MCP) are converted into their respective dictionary representations. - Options and Response Format: Model options (temperature, top-p, max tokens, etc.) are extracted from the
model.optionsblock. If anoutputSchemais defined, it is converted into a Pydantic model for structured output enforcement. - Agent Instantiation: Finally, the factory calls the standard
Agent()constructor with all resolved components, producing an instance that is identical in behavior to one created via direct Python construction.
Supported Providers
The built-in provider mapping supports the following provider types:
| Provider Key | Client Class | Package |
|---|---|---|
AzureOpenAI.Chat |
AzureOpenAIChatClient |
agent_framework.azure
|
AzureOpenAI.Responses |
AzureOpenAIResponsesClient |
agent_framework.azure
|
AzureOpenAI.Assistants |
AzureOpenAIAssistantsClient |
agent_framework.azure
|
OpenAI.Chat |
OpenAIChatClient |
agent_framework.openai
|
OpenAI.Responses |
OpenAIResponsesClient |
agent_framework.openai
|
OpenAI.Assistants |
OpenAIAssistantsClient |
agent_framework.openai
|
AzureAIClient |
AzureAIClient |
agent_framework.azure
|
Anthropic.Chat |
AnthropicChatClient |
agent_framework.anthropic
|
Safe Mode
The factory operates in safe mode by default (safe_mode=True). In safe mode, PowerFx expressions embedded in YAML fields (prefixed with =) cannot access environment variables via the Env symbol. This prevents untrusted YAML documents from exfiltrating sensitive configuration. Safe mode can be disabled when the YAML source is trusted, enabling expressions like =Env.AZURE_OPENAI_MODEL to resolve dynamically at load time.
Equivalence Guarantee
The central guarantee of this principle is that the Agent produced by YAML loading is functionally identical to one constructed programmatically:
# Programmatic construction
from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient
agent_programmatic = Agent(
client=OpenAIChatClient(model_id="gpt-4o"),
name="MyAgent",
instructions="You are helpful.",
tools=[get_weather],
)
# Declarative YAML construction (equivalent)
from agent_framework.declarative import AgentFactory
factory = AgentFactory(bindings={"get_weather": get_weather})
agent_declarative = factory.create_agent_from_yaml("""
kind: Prompt
name: MyAgent
instructions: You are helpful.
model:
id: gpt-4o
provider: OpenAI
apiType: Chat
tools:
- kind: function
name: get_weather
description: Get current weather
bindings:
- name: get_weather
""")
# Both agents behave identically
Theoretical Basis
The YAML Agent Loading principle is grounded in the declarative configuration paradigm:
Agent = parse(YAML) -> validate(schema) -> resolve(provider) -> construct(client, tools, options)
This approach provides several architectural benefits:
- Separation of definition and execution: Agent behavior is defined in data (YAML) rather than code, enabling non-developers to author and modify agent configurations.
- Portability: YAML definitions can be stored, versioned, and shared independently of the Python application code. The same YAML file can be loaded by different applications using different factory configurations.
- Late binding: Provider resolution and client construction happen at load time rather than import time, allowing the same YAML definition to target different backends depending on the factory's configuration.
- Extensibility: The
additional_mappingsparameter allows third-party providers to participate in the declarative loading pipeline without modifying framework internals. - Safe defaults: Safe mode prevents environment variable access in PowerFx expressions by default, ensuring that YAML files from untrusted sources cannot leak sensitive data.
Usage
Loading from a File
from agent_framework.declarative import AgentFactory
factory = AgentFactory()
agent = factory.create_agent_from_yaml_path("agents/support_agent.yaml")
response = await agent.run("Help me with my order")
print(response.text)
Loading from an Inline String
from agent_framework.declarative import AgentFactory
yaml_content = """
kind: Prompt
name: TranslationAgent
instructions: You are a translation assistant.
model:
id: gpt-4o
provider: OpenAI
apiType: Responses
"""
factory = AgentFactory()
agent = factory.create_agent_from_yaml(yaml_content)
Async Loading for Provider-Based Agents
from agent_framework.declarative import AgentFactory
factory = AgentFactory(
client_kwargs={"credential": credential},
default_provider="AzureAI.ProjectProvider",
)
agent = await factory.create_agent_from_yaml_async(yaml_content)
Loading with Tool Bindings
from agent_framework.declarative import AgentFactory
def get_weather(location: str) -> str:
return f"Weather in {location}: sunny, 22C"
factory = AgentFactory(bindings={"get_weather": get_weather})
agent = factory.create_agent_from_yaml_path("agent_with_tools.yaml")