Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Principle:Microsoft Agent framework YAML Agent Loading

From Leeroopedia
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:

  1. 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.
  2. Schema Validation and Dispatch: The dictionary is passed through agent_schema_dispatch(), which inspects the kind field and instantiates the corresponding model class. For agent creation, only kind: Prompt (mapped to the PromptAgent model) is supported. Any other kind raises a DeclarativeLoaderError.
  3. Provider Resolution: The factory resolves the model provider using the model.provider and optional model.apiType fields. 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 the additional_mappings constructor argument.
  4. 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.connection block 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.
  5. Tool Binding: The tools list from the YAML is parsed into framework-compatible tool objects. Function tools are matched against the bindings dictionary 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.
  6. Options and Response Format: Model options (temperature, top-p, max tokens, etc.) are extracted from the model.options block. If an outputSchema is defined, it is converted into a Pydantic model for structured output enforcement.
  7. 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_mappings parameter 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")

Related Pages

Implemented By

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment