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.

Implementation:Microsoft Agent framework Declarative Tool Function Pattern

From Leeroopedia
Property Value
Implementation Name Declarative Tool Function Pattern
SDK Microsoft Agent Framework
Repository Microsoft Agent Framework
Type Pattern Doc (user-defined interface)
Domains Declarative_Systems, Agent_Architecture
Sample python/samples/getting_started/declarative/get_weather_agent.py, Lines L12-14
Interface def func(param: type, ...) -> ReturnType: (plain callable, no decorator)

Overview

The Declarative Tool Function Pattern describes the user-defined callable interface used to implement tool functions for declarative (YAML-defined) agents in the Microsoft Agent Framework. Unlike the @tool decorator approach, declarative tool functions are plain Python functions with no framework-specific decoration. They are connected to YAML tool definitions at agent creation time through the AgentFactory bindings parameter.

This is a Pattern Doc -- it documents a user-defined interface rather than a specific framework API. The framework defines the binding contract; users provide the function implementation.

Interface Contract

Function Signature

Declarative tool functions are ordinary Python callables. The function's parameters must correspond to the parameter schema defined in the YAML tool definition:

def function_name(param1: type1, param2: type2 = default) -> ReturnType:
    """Docstring describing the tool's purpose."""
    ...

Binding Mechanism

The function is bound to its YAML tool definition via the AgentFactory constructor's bindings parameter:

from agent_framework_declarative import AgentFactory

factory = AgentFactory(
    client=client,
    bindings={"binding_key": function_name},
)

The binding_key string must match the key declared under bindings: in the YAML tool definition:

tools:
  - kind: function
    name: ToolDisplayName
    bindings:
      binding_key: binding_key

Code Reference

Sample Source

From python/samples/getting_started/declarative/get_weather_agent.py, lines L12-14:

# Plain Python function - no @tool decorator needed
def get_weather(
    location: str,
    unit: Literal["celsius", "fahrenheit"] = "celsius",
) -> str:
    """A simple function tool to get weather information."""
    return f"The weather in {location} is 22 degrees {unit}."

Full Wiring Example

from typing import Literal
from agent_framework_declarative import AgentFactory

# Step 1: Define the plain Python function
def get_weather(
    location: str,
    unit: Literal["celsius", "fahrenheit"] = "celsius",
) -> str:
    """A simple function tool to get weather information."""
    return f"The weather in {location} is 22 degrees {unit}."

# Step 2: Create AgentFactory with bindings
factory = AgentFactory(
    client=client,
    bindings={"get_weather": get_weather},  # key matches YAML bindings
)

# Step 3: Load YAML and create agent
agent = factory.create_agent_from_yaml(yaml_str)

# Step 4: Run the agent
response = await agent.run("What is the weather in Seattle?")

Corresponding YAML Definition

type: prompt
name: WeatherAgent
instructions: You help users check the weather.
tools:
  - kind: function
    name: GetWeather
    description: Get weather for a location
    bindings:
      get_weather: get_weather
    parameters:
      type: object
      properties:
        location:
          type: string
          description: The city name
        unit:
          type: string
          enum: ["celsius", "fahrenheit"]
          default: "celsius"
      required:
        - location

I/O Contract

Inputs

Parameter Type Description
Function parameters As defined by YAML schema The parameters the function accepts must match the tool's parameter schema declared in YAML. Standard Python type hints (str, int, Literal[...], etc.) should be used for clarity.
bindings dict key str The string key used in AgentFactory(bindings={"key": func}). Must match the YAML tool's bindings key exactly.

Outputs

Return Type Description
str (typical) The function's return value is serialized and sent back to the LLM as the tool result. String return types are most common.
Other serializable types Any type that the framework can serialize to a string representation for the LLM.

Data Flow

The declarative tool function sits within the following execution flow:

Step Component Action
1 YAML Definition Declares the tool's name, description, parameter schema, and binding key.
2 AgentFactory Receives the bindings dictionary mapping keys to Python callables. Resolves YAML tool definitions against bindings at agent creation time.
3 LLM Generates a structured tool call based on the tool schema provided.
4 Agent Runtime Intercepts the tool call, deserializes arguments, and invokes the bound Python function.
5 Tool Function Executes with the deserialized arguments and returns a result.
6 Agent Runtime Serializes the return value and sends it back to the LLM as a tool result.

Contrast with @tool Decorator

Aspect @tool Decorator Pattern Declarative Binding Pattern
Function decoration Required (@tool) Not required (plain function)
Schema generation Automatic from type hints at decoration time Defined externally in YAML
Registration timing Module import time Agent creation time via AgentFactory
Configuration location Co-located in Python code Split between YAML (schema) and Python (logic)
Swappability Fixed at decoration Swappable by changing bindings dict

Implementation Guidelines

  1. Match binding keys exactly -- A mismatch between the Python bindings dictionary key and the YAML bindings key will cause the tool to be unresolved at runtime.
  2. Use type hints for documentation -- Although the schema is defined in YAML, type-annotating the Python function improves readability and enables IDE autocompletion.
  3. Keep functions pure when possible -- Tool functions that are free of side effects are easier to test and reason about.
  4. Test independently of YAML -- Because the function is a plain callable, it can be unit-tested by invoking it directly without the YAML loading or agent creation machinery.
  5. Support both sync and async -- The binding mechanism supports both synchronous and asynchronous functions. Use async when the tool implementation involves I/O operations.

Error Handling

Scenario Behavior
Binding key mismatch The AgentFactory cannot resolve the YAML tool to a Python callable. An error is raised during agent creation.
Function raises an exception The agent runtime handles the exception according to its error handling policy (typically returning an error message to the LLM).
Parameter type mismatch The framework deserializes LLM-provided arguments according to the YAML schema. If the Python function expects different types, a runtime error may occur.

Related Pages

Categories

Page Connections

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