Skip to content

Structured Responses: Python vs YAML

This example demonstrates two ways to define structured responses in LLMling-agent:

  • Using Python Pydantic models
  • Using YAML response definitions
  • Type validation and constraints
  • Agent integration with structured outputs

Configuration

Our structured_agents.yml defines response types and agents:

# Define response type in YAML
responses:
    YamlResult:
        type: inline
        description: "Sentiment analysis result"
        fields:
            sentiment:
                type: str
                description: "Overall sentiment"
            confidence:
                type: float
                description: "Confidence score"
            mood:
                type: str
                description: "Detected mood"
                constraints:
                    min_length: 3
                    max_length: 20

agents:
    analyzer:
        model: openai:gpt-4o-mini
        system_prompts:
            - Analyze text sentiment and mood.
        # Use YAML-defined response type
        result_type: YamlResult

Implementation

Here's how to use both approaches:

from pydantic import BaseModel
from llmling_agent import Agent, AgentsManifest


class PythonResult(BaseModel):
    """Structured response defined in Python."""
    main_point: str
    is_positive: bool


async def example_structured_response():
    # Example 1: Python-defined structure
    agent = Agent[None](
            model="openai:gpt-4o-mini",
            system_prompt="Summarize text in a structured way.",
        )
        async with agent.to_structured(PythonResult) as summarizer:
            result = await summarizer.run("I love this new feature!")
            summary = result.data
            print("\nPython-defined Response:")
            print(f"Main point: {summary.main_point}")
            print(f"Is positive: {summary.is_positive}")

    # Example 2: YAML-defined structure
    # Note: For programmatic use, Python definitions are recommended
    manifest = AgentsManifest.from_yaml(AGENT_CONFIG)
    async with AgentPool[None](manifest) as pool:
        analyzer = pool.get_agent("analyzer")
        result = await analyzer.run("I'm really excited about this project!")
        analysis = result.data
        print("\nYAML-defined Response:")
        # Type hints aren't available for dynamic models
        print(f"Sentiment: {analysis.sentiment}")  # type: ignore
        print(f"Confidence: {analysis.confidence:.2f}")  # type: ignore
        print(f"Mood: {analysis.mood}")  # type: ignore


if __name__ == "__main__":
    import asyncio
    asyncio.run(example_structured_response())

How It Works

  1. Python-defined Responses:

  2. Use Pydantic models

  3. Full IDE support and type checking
  4. Best for programmatic use
  5. Inline field documentation

  6. YAML-defined Responses:

  7. Define in configuration

  8. Include validation constraints
  9. Best for configuration-driven workflows
  10. Self-documenting fields

Example Output:

Python-defined Response:
Main point: User expresses enthusiasm for new feature
Is positive: true

YAML-defined Response:
Sentiment: positive
Confidence: 0.95
Mood: excited

This demonstrates:

  • Two ways to define structured outputs
  • Validation and constraints
  • Integration with type system
  • Trade-offs between approaches