Response Formats
Configure how a formation returns text
MUXI can instruct the Overlord to return markdown, plain text, or a JSON-wrapped response. For domain-specific structured data, describe the required shape in the agent instructions and validate it in your application.
The Problem: Text Responses
Traditional agents return unstructured text:
User: "Extract customer info from this email"
Agent: "The customer's name is John Smith, email is john@example.com,
and phone is 555-0123."
Problem: How do you extract that data programmatically? - Parse with regex? (brittle) - Use another LLM call? (expensive) - String manipulation? (error-prone)
The Solution: Formation-Wide Formatting
Tell the agent what format you want:
overlord:
response:
format: json
Now you get:
{
"name": "John Smith",
"email": "john@example.com",
"phone": "555-0123"
}
The JSON wrapper is machine-readable. MUXI does not enforce a domain schema for the content inside it.
Response Formats
MUXI supports three response formats:
1. Markdown (Default)
overlord:
response:
format: markdown
Best for:
- Documentation
- Rich text with formatting
- Human-readable content
Example output:
# Cloud Computing Benefits
## Cost Efficiency
- **Pay-as-you-use** pricing
- Reduced infrastructure costs
## Scalability
- Elastic resources
- Automatic scaling
2. Plain Text
overlord:
response:
format: text
Best for:
- CLI applications
- Log files
- Simple integrations
Example output:
Cloud computing offers three key benefits:
1. Cost Efficiency
Reduces infrastructure costs through pay-as-you-use pricing.
2. Scalability
Provides elastic resources that grow with your needs.
3. JSON (Structured)
overlord:
response:
format: json
Best for:
- REST APIs
- Data extraction
- Programmatic processing
- Integration with JSON-based systems
Example output:
{
"content": "Cloud computing offers cost efficiency, scalability, and global accessibility.",
"type": "response",
"format": "json"
}
How It Works
Format Instructions
MUXI adds format-specific instructions to the agent's prompt:
For JSON mode:
"Format your response as valid JSON. Use appropriate data structures
(objects, arrays, strings, numbers, booleans) for the content."
For Plain Text:
"Format your response as plain text with no markdown, HTML, or special
characters. Use simple line breaks and spacing only."
The setting applies to the formation. The chat API does not accept a
per-request format override.
Validation
JSON mode serializes the final response into a valid JSON wrapper. It does not validate a custom schema. Markdown and text remain strings.
Use Cases
Data Extraction
# Extract structured data from text
overlord:
response:
format: json
agents:
- id: extractor
system_message: |
Extract customer information and return as JSON with fields:
name, email, phone, company
Input: "John Smith from Acme Corp called, email john@acme.com, phone 555-0123"
Output:
{
"name": "John Smith",
"email": "john@acme.com",
"phone": "555-0123",
"company": "Acme Corp"
}
API Responses
import json
from muxi import FormationClient
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="<your-client-key>",
)
# Request JSON format
response = formation.chat(
{"message": "Analyze: " + text},
user_id="user_123",
)
# The formation is configured for JSON mode.
return json.loads(response["response"])
import { FormationClient } from '@muxi/sdk';
const formation = new FormationClient({
serverUrl: 'http://localhost:7890',
formationId: 'my-assistant',
clientKey: '<your-client-key>'
});
// Request JSON format
const response = await formation.chat({
message: Analyze: ${text}
}, 'user_123');
return JSON.parse(response.response);
import (
"encoding/json"
muxi "github.com/muxi-ai/muxi-go"
)
formation := muxi.NewFormationClient(&muxi.FormationConfig{
ServerURL: "http://localhost:7890",
FormationID: "my-assistant",
ClientKey: "<your-client-key>",
})
// Request JSON format
response, _ := formation.Chat(ctx, &muxi.ChatRequest{
Message: "Analyze: " + text,
})
var result map[string]interface{}
json.Unmarshal([]byte(response.Response), &result)
return result
Form Filling
overlord:
response:
format: json
agents:
- id: form_filler
system_message: |
Fill out forms by extracting data from conversations.
Return JSON matching the form schema.
User: "I want to sign up. I'm Alice Johnson, alice@example.com, in New York"
Output:
{
"first_name": "Alice",
"last_name": "Johnson",
"email": "alice@example.com",
"city": "New York"
}
Database Inserts
import json
from muxi import FormationClient
import json
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="<your-client-key>",
)
# Extract data
response = formation.chat(
{
"message": "Extract product info from this description: ...",
},
user_id="user_123",
)
# JSON mode wraps the agent's text in a JSON response object.
wrapper = json.loads(response["response"])
product_data = json.loads(wrapper["content"])
db.insert("products", product_data)
import { FormationClient } from '@muxi/sdk';
const formation = new FormationClient({
serverUrl: 'http://localhost:7890',
formationId: 'my-assistant',
clientKey: '<your-client-key>'
});
// Extract data
const response = await formation.chat({
message: 'Extract product info from this description: ...'
}, 'user_123');
const wrapper = JSON.parse(response.response);
const productData = JSON.parse(wrapper.content);
await db.insert('products', productData);
import (
"encoding/json"
muxi "github.com/muxi-ai/muxi-go"
)
formation := muxi.NewFormationClient(&muxi.FormationConfig{
ServerURL: "http://localhost:7890",
FormationID: "my-assistant",
ClientKey: "<your-client-key>",
})
// Extract data
response, _ := formation.Chat(ctx, &muxi.ChatRequest{
Message: "Extract product info from this description: ...",
})
var wrapper struct {
Content string json:"content"
}
json.Unmarshal([]byte(response.Response), &wrapper)
var productData map[string]interface{}
json.Unmarshal([]byte(wrapper.Content), &productData)
db.Insert("products", productData)
Configuration
Formation-Wide Default
# formation.afs
overlord:
response:
format: json # All responses are JSON
The configured format applies to every chat request handled by the formation. Change the formation configuration and restart or redeploy it to change the default.
With Streaming
All formats work with streaming:
from muxi import FormationClient
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="<your-client-key>",
)
# Stream JSON response
for event in formation.chat_stream(
{"message": "Analyze this..."},
user_id="user_123",
):
if event.get("event") == "message":
payload = json.loads(event.get("data", "{}"))
token = payload.get("token")
if isinstance(token, str):
print(token, end="", flush=True)
import { FormationClient } from '@muxi/sdk';
const formation = new FormationClient({
serverUrl: 'http://localhost:7890',
formationId: 'my-assistant',
clientKey: '<your-client-key>'
});
// Stream JSON response
for await (const chunk of formation.chatStream(
{ message: 'Analyze this...' },
'user_123'
)) {
if (typeof chunk.token === 'string') {
process.stdout.write(chunk.token);
}
}
formation := muxi.NewFormationClient(&muxi.FormationConfig{
ServerURL: "http://localhost:7890",
FormationID: "my-assistant",
ClientKey: "<your-client-key>",
})
stream, _ := formation.ChatStream(ctx, &muxi.ChatRequest{
Message: "Analyze this...",
UserID: "user_123",
})
for chunk := range stream {
if token, ok := chunk.Raw["token"].(string); ok {
fmt.Print(token)
}
}
Collect the text chunks and parse the completed value according to the formation's response format.
Best Practices
Clear Instructions
agents:
- id: extractor
system_message: |
Extract information and return as JSON.
Always include fields: name, email, phone, company.
Use null for missing fields.
Clear instructions → better structured output.
Schema in Prompt
from muxi import FormationClient
import json
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="<your-client-key>",
)
schema = {
"name": "string",
"email": "string",
"phone": "string | null",
"company": "string | null"
}
response = formation.chat(
{"message": f"""Extract customer info. Return JSON matching this schema:
{json.dumps(schema, indent=2)}
Text: {text}"""},
user_id="user_123",
)
import { FormationClient } from '@muxi/sdk';
const formation = new FormationClient({
serverUrl: 'http://localhost:7890',
formationId: 'my-assistant',
clientKey: '<your-client-key>'
});
const schema = {
name: 'string',
email: 'string',
phone: 'string | null',
company: 'string | null'
};
const response = await formation.chat({
message: ___CODE_SPAN_0___,
}, 'user_123');
Providing schema improves accuracy.
Error Handling
import json
try:
wrapper = json.loads(response["response"])
data = json.loads(wrapper["content"])
except json.JSONDecodeError:
# Invalid JSON - retry or use fallback
logger.error("Agent returned invalid JSON")
try {
const wrapper = JSON.parse(response.response);
const data = JSON.parse(wrapper.content);
} catch (e) {
// Invalid JSON - retry or use fallback
console.error('Agent returned invalid JSON');
}
Always validate, even with structured output.
Limitations
Not a Schema Validator
JSON mode guarantees a valid outer wrapper, but it does not validate a schema for the agent-generated content:
// Agent might return this:
{"name": "John", "extra_field": "something"}
// Even if you only asked for name and email
Use Pydantic or JSON Schema validation if you need strict schema enforcement.
LLM Quality Dependent
Quality depends on:
- LLM model capabilities
- Prompt clarity
- Input complexity
More capable models generally produce more reliable structured content.
Not Perfect
Agents may occasionally:
- Return invalid JSON (rare with good models)
- Include extra fields
- Use unexpected data types
Always validate in production.
Why This Matters
| Text Responses | Structured Output |
|---|---|
| Parse with regex | Parse a JSON wrapper |
| Fragile, breaks easily | Explicit application validation |
| Extra code needed | Machine-readable |
| Hard to integrate | API-ready |
| Unstructured | Machine-readable envelope |
The result: Agents that return data, not just text.
Quick Setup
# formation.afs
overlord:
response:
format: json # or "text", "markdown"
agents:
- id: assistant
system_message: |
You are a helpful assistant.
Return responses as valid JSON.
Learn More
- Deep Dive: Response Formats - Technical implementation
- Tools & MCP - Tools can also return structured data
- Build Custom UI - Using structured output in UIs