Skip to main content
Structured outputs enable agents to return responses in a specific format, such as JSON objects, lists, or Pydantic models. This is essential for integrating agents into applications and workflows. There are two separate controls:
  • output_type decides how agent.run() formats the conversation it returns.
  • A function-calling schema in tools_list_dictionary makes the model answer with arguments that match your schema.

Output Types

Swarms supports multiple output formats through the output_type parameter. output_type controls how the conversation transcript (agent.short_memory) is formatted when agent.run() returns — it is not a schema parser. In particular:
  • "str-all-except-first" (default) — every message after the system prompt and the first input, contents joined into one string without role labels. In a plain run the first input is your task, so you get the agent’s answer
  • "final" / "last" — just the content of the last message. This is a string for a text answer, and a list of tool-call dicts when the model answered with a function call
  • "str" / "string" / "all" — the full conversation as one string, with a timestamp and role label on each message
  • "list" — the conversation as a list of {"role", "content"} dicts
  • "dict" / "dictionary" — the full conversation history as a Python list of message dicts, including each message’s timestamp and message_id (despite the name, this is a list, not a single dict)
  • "json" — the full conversation history serialized as a JSON string (an array of message dicts, not a single schema-shaped object)
  • "yaml" — the conversation history as a YAML string
  • "dict-all-except-first" — every message after the system prompt and the first input, as a list of message dicts. This is the default output_type of several multi-agent harnesses (HeavySwarm, HierarchicalSwarm, ConcurrentWorkflow, LLMCouncil, PlannerWorkerSwarm, and others)
  • "list-final" — the content of the last message, wrapped in a single-item list
  • "dict-final" — the content of the last message, as a (content, content) tuple
The "xml" output type was removed. "basemodel" is still accepted by the type hint, but the formatter does not handle it: a run with output_type="basemodel" raises ValueError after the model has answered. Use "final" and validate with Pydantic yourself, as shown below.

Function-Calling Schemas

The reliable way to get schema-shaped data is to give the agent a function schema in tools_list_dictionary and no Python callable to run. The model answers with a function call whose arguments follow your schema, and the agent returns that call to you instead of executing anything. With output_type="final", run() returns a list of tool-call dicts:

Basic JSON Schema

Define the shape with a Pydantic model and convert it with BaseTool().base_model_to_dict(), which returns an OpenAI tool schema:
The request is sent with tool_choice="auto", so the model may still answer in plain text. Name the function in your task or system prompt, and check whether the result is a list before parsing it. Keep max_loops=1. No callable runs the function, so a later loop only sees a (no result recorded ...) placeholder for the call.

Multiple Output Schemas

Give the agent several schemas and branch on the function the model chose:

Hand-Written JSON Schemas

You can also pass an OpenAI tool schema as a plain dict:

Tool Schema

Using tool_schema Parameter

tool_schema takes a single Pydantic model and writes its schema into the agent’s memory as guidance. It does not send a function to the model and does not parse the reply, so you get the model’s text back and parse it yourself:
Use output_type="final" with tool_schema. The schema is stored as the first message after the system prompt, so the default "str-all-except-first" returns your task followed by the answer. If the model wraps its JSON in prose or code fences, json.loads fails; prefer tools_list_dictionary when you need guaranteed structure.
list_base_models raises TypeError when the agent is constructed in swarms 15.0.3, so you cannot use it to pass several Pydantic models. Pass several schemas through tools_list_dictionary instead, as in Multiple Output Schemas.

Complex Output Structures

Nested Models

Nested models and enums become $defs references in the generated schema:

Lists and Arrays

Validation and Constraints

The schema tells the model what to produce, but nothing checks the reply for you. Validate the parsed arguments with your Pydantic model and handle ValidationError.

Field Validation

Enums and Choices

Output Processing

JSON Output

output_type="json" serializes the entire conversation history (a list of {"role", "content", ...} message dicts) to a JSON string — it does not extract a single task-specific object with your own keys. For a task-specific structured payload, use a schema in tools_list_dictionary with output_type="final", as shown above.

Dictionary Output

output_type="dict" (or "dictionary") returns the full conversation history as a Python list of message dicts, not a single dict keyed by your schema’s fields. Index it as result[-1]["content"] to get the last message, then parse that content yourself.

Working with Responses

Function Calling Response

When you pass Python callables in tools, the agent runs the tool calls itself and records their results, so the return value is the conversation formatted by output_type, not raw tool calls:
See Agent Tools for callable tools and how their output is summarized.

Best Practices

1. Use Descriptive Field Names

2. Add Field Descriptions

3. Use Appropriate Constraints

4. Provide Examples in Descriptions

5. Give Each Schema a Docstring

A Pydantic model’s docstring becomes the function description the LLM sees, and the class name becomes the function name. Say what the function records, and name the function in your task.

Next Steps

Agent Tools

Add tools to extend agent capabilities

Creating Agents

Learn how to create agents

Reference

  • Output type formatting: swarms/utils/history_output_formatter.py; the accepted values are in swarms/utils/output_types.py
  • Pydantic to tool schema: BaseTool.base_model_to_dict in swarms/tools/base_tool.py, built on swarms/tools/pydantic_to_json.py
  • Tool-call parsing: ToolManager.parse_response in swarms/agents/tool_manager.py
  • tool_schema and list_base_models handling: ToolManager.handle_tool_schema_ops in swarms/agents/tool_manager.py