Get typed JSON responses from your agent using output_schema.
How It Works
When you set output_schema on an agent config, the agent's finish tool is configured to require output matching your schema. Instead of free-form text, the agent returns structured JSON.
- You define a JSON Schema in
output_schema - The finish tool's parameters are set to your schema
- The agent calls
finishwith data matching the schema - You get predictable, parseable output
Requires internal_tools.finish to be enabled (on by default).
Basic Example
1from inferencesh import inference23client = inference(api_key="inf_...")45agent = client.agent({6 "core_app": { "ref": "infsh/claude-sonnet-4@latest" },7 "system_prompt": "Analyze the sentiment of the given text.",8 "output_schema": {9 "type": "object",10 "properties": {11 "sentiment": {12 "type": "string",13 "enum": ["positive", "negative", "neutral"],14 "description": "Overall sentiment"15 },16 "confidence": {17 "type": "number",18 "description": "Confidence score between 0 and 1"19 },20 "summary": {21 "type": "string",22 "description": "One-sentence summary"23 }24 },25 "required": ["sentiment", "confidence", "summary"]26 },27 "internal_tools": { "finish": True }28})2930output = agent.run("This product exceeded all my expectations!")31# output = {"sentiment": "positive", "confidence": 0.95, "summary": "..."}Reading the Output
The simplest way to get structured output is agent.run() — it sends the message, waits for the agent to finish, and returns chat.output directly:
1output = agent.run("This product exceeded all my expectations!")2print(output)3# {"sentiment": "positive", "confidence": 0.95, "summary": "Very positive product review"}If you need more control, use sendMessage + getChat separately:
1response = agent.send_message("This product exceeded all my expectations!")2chat = agent.get_chat()3print(chat.get("output"))In the React provider, access it via the chat state:
1const { chat } = useAgentChat();23if (chat?.output) {4 console.log(chat.output); // structured finish output5}Using Schema Helpers
You can use the SDK's built-in schema helpers instead of writing raw JSON Schema:
1from inferencesh import obj, string, number, array, enum_of, optional23schema = obj({4 "sentiment": enum_of(["positive", "negative", "neutral"], "Overall sentiment"),5 "confidence": number("Confidence score 0-1"),6 "summary": string("One-sentence summary"),7 "keywords": array(string(), "Extracted keywords"),8 "language": optional(string("Detected language")),9})1011agent = client.agent({12 "core_app": { "ref": "infsh/claude-sonnet-4@latest" },13 "output_schema": schema,14 "internal_tools": { "finish": True }15})Schema Format
output_schema accepts standard JSON Schema objects:
1{2 "type": "object",3 "properties": {4 "field_name": {5 "type": "string",6 "description": "What this field contains"7 }8 },9 "required": ["field_name"]10}Supported types: string, number, integer, boolean, array, object
Use enum for constrained values:
1{ "type": "string", "enum": ["option_a", "option_b"] }Use description on every field — it helps the LLM understand what to put there.
Use Cases
Data Extraction
1agent = client.agent({2 "core_app": { "ref": "infsh/claude-sonnet-4@latest" },3 "system_prompt": "Extract contact information from the given text.",4 "output_schema": {5 "type": "object",6 "properties": {7 "name": { "type": "string" },8 "email": { "type": "string" },9 "phone": { "type": "string" },10 "company": { "type": "string" }11 },12 "required": ["name"]13 },14 "internal_tools": { "finish": True }15})Classification
1agent = client.agent({2 "core_app": { "ref": "infsh/claude-sonnet-4@latest" },3 "system_prompt": "Classify the support ticket.",4 "output_schema": {5 "type": "object",6 "properties": {7 "category": {8 "type": "string",9 "enum": ["billing", "technical", "account", "other"]10 },11 "priority": {12 "type": "string",13 "enum": ["low", "medium", "high", "urgent"]14 },15 "suggested_action": { "type": "string" }16 },17 "required": ["category", "priority"]18 },19 "internal_tools": { "finish": True }20})Multi-step Analysis with Tools
Structured output works alongside other tools. The agent can use tools to gather information, then return structured results:
1from inferencesh import tool, string, app_tool23search = (4 tool("search_docs")5 .describe("Search internal documentation")6 .param("query", string("Search query"))7 .handler(lambda args: search_index(args["query"]))8)910agent = client.agent({11 "core_app": { "ref": "infsh/claude-sonnet-4@latest" },12 "system_prompt": "Research the topic using available tools, then summarize findings.",13 "tools": [search],14 "output_schema": {15 "type": "object",16 "properties": {17 "findings": {18 "type": "array",19 "items": {20 "type": "object",21 "properties": {22 "title": { "type": "string" },23 "relevance": { "type": "number" },24 "summary": { "type": "string" }25 }26 }27 },28 "recommendation": { "type": "string" }29 },30 "required": ["findings", "recommendation"]31 },32 "internal_tools": { "finish": True }33})Tips
- Always include
required— without it, the agent may omit fields - Use
descriptionon every property — it acts as instructions for the LLM - Use
enumfor categorical data — constrains output to valid values - Keep schemas focused — one clear purpose per agent, not a kitchen sink
- Set a clear
system_prompt— tell the agent what to do, the schema tells it how to format the result