Get model responses that adhere to a JSON schema for reliable data extraction and structured outputs.
ASI1 supports structured output through the response_format parameter, ensuring responses conform to your specified JSON schema. This is essential for building reliable applications that parse model outputs programmatically.
The simplest way to get structured output is using the OpenAI SDK with response_format:
1 import os 2 import json 3 from openai import OpenAI 4 5 client = OpenAI( 6 api_key=os.getenv("ASI_ONE_API_KEY"), 7 base_url="https://api.asi1.ai/v1" 8 ) 9 10 response = client.chat.completions.create( 11 model="asi1", 12 messages=[ 13 {"role": "system", "content": "Extract the requested information as JSON."}, 14 {"role": "user", "content": "Extract: John Smith is a 32 year old software engineer from San Francisco."} 15 ], 16 response_format={ 17 "type": "json_schema", 18 "json_schema": { 19 "name": "person_info", 20 "strict": True, 21 "schema": { 22 "type": "object", 23 "properties": { 24 "name": {"type": "string"}, 25 "age": {"type": "integer"}, 26 "occupation": {"type": "string"}, 27 "city": {"type": "string"} 28 }, 29 "required": ["name", "age", "occupation", "city"], 30 "additionalProperties": False 31 } 32 } 33 } 34 ) 35 36 result = json.loads(response.choices[0].message.content) 37 print(f"Name: {result['name']}") 38 print(f"Age: {result['age']}") 39 print(f"Occupation: {result['occupation']}") 40 print(f"City: {result['city']}")
For Python developers, LangChain’s with_structured_output provides a cleaner, type-safe approach:
1 import os 2 from langchain_openai import ChatOpenAI 3 from pydantic import BaseModel, Field 4 from typing import List 5 6 # Define your schema as a Pydantic model 7 class Product(BaseModel): 8 """A product extracted from text.""" 9 name: str = Field(description="Product name") 10 price: float = Field(description="Price in USD") 11 category: str = Field(description="Product category") 12 13 class ProductList(BaseModel): 14 """A list of products.""" 15 products: List[Product] = Field(description="List of extracted products") 16 17 llm = ChatOpenAI( 18 model="asi1", 19 base_url="https://api.asi1.ai/v1", 20 api_key=os.getenv("ASI_ONE_API_KEY"), 21 ) 22 23 # Create a structured output chain 24 structured_llm = llm.with_structured_output(ProductList) 25 26 text = """ 27 Our store has the following items: 28 - Wireless Mouse ($29.99) - Electronics 29 - Organic Coffee Beans ($14.50) - Groceries 30 - Running Shoes ($89.00) - Sports 31 """ 32 33 result = structured_llm.invoke(f"Extract all products from this text:\n{text}") 34 35 for product in result.products: 36 print(f"- {product.name}: ${product.price} ({product.category})")
Here’s a more comprehensive example with nested objects and arrays:
1 import os 2 import json 3 from openai import OpenAI 4 5 client = OpenAI( 6 api_key=os.getenv("ASI_ONE_API_KEY"), 7 base_url="https://api.asi1.ai/v1" 8 ) 9 10 # Complex schema with nested objects 11 response_format = { 12 "type": "json_schema", 13 "json_schema": { 14 "name": "order_summary", 15 "strict": True, 16 "schema": { 17 "type": "object", 18 "additionalProperties": False, 19 "properties": { 20 "order_id": {"type": "string"}, 21 "customer": { 22 "type": "object", 23 "additionalProperties": False, 24 "properties": { 25 "name": {"type": "string"}, 26 "email": {"type": "string"} 27 }, 28 "required": ["name", "email"] 29 }, 30 "items": { 31 "type": "array", 32 "items": { 33 "type": "object", 34 "additionalProperties": False, 35 "properties": { 36 "sku": {"type": "string"}, 37 "name": {"type": "string"}, 38 "quantity": {"type": "integer"}, 39 "unit_price": {"type": "number"} 40 }, 41 "required": ["sku", "name", "quantity", "unit_price"] 42 } 43 }, 44 "total": {"type": "number"}, 45 "currency": {"type": "string"} 46 }, 47 "required": ["order_id", "customer", "items", "total", "currency"] 48 } 49 } 50 } 51 52 response = client.chat.completions.create( 53 model="asi1", 54 messages=[ 55 {"role": "system", "content": "Generate order data matching the schema."}, 56 {"role": "user", "content": "Create a sample order for customer Jane Doe (jane@example.com) with 2 items totaling $150."} 57 ], 58 response_format=response_format 59 ) 60 61 order = json.loads(response.choices[0].message.content) 62 print(json.dumps(order, indent=2))
For direct API integration without SDKs:
1 import os 2 import json 3 import requests 4 from typing import List 5 from openai import OpenAI 6 7 8 # ---- Config from environment ---- 9 LLM_API_ENDPOINT = os.getenv("LLM_API_ENDPOINT", "https://api.asi1.ai/v1") 10 LLM_API_KEY = os.getenv("LLM_API_KEY", "your-api-key") 11 LLM_MODEL = os.getenv("LLM_MODEL", "asi1") 12 13 # Initialize OpenAI client with ASI1 API 14 client = OpenAI( 15 api_key=LLM_API_KEY, 16 base_url=LLM_API_ENDPOINT 17 ) 18 19 headers = { 20 "Authorization": f"Bearer {LLM_API_KEY}", 21 "Content-Type": "application/json", 22 } 23 24 # ---- Target JSON schema (order summary) ---- 25 response_format = { 26 "type": "json_schema", 27 "json_schema": { 28 "name": "order_summary", 29 "strict": True, 30 "schema": { 31 "type": "object", 32 "additionalProperties": False, 33 "properties": { 34 "order_id": {"type": "string"}, 35 "total": {"type": "number"}, 36 "currency": {"type": "string"}, 37 "items": { 38 "type": "array", 39 "minItems": 1, 40 "items": { 41 "type": "object", 42 "additionalProperties": False, 43 "properties": { 44 "sku": {"type": "string"}, 45 "name": {"type": "string"}, 46 "qty": {"type": "integer", "minimum": 1}, 47 "unit_price": {"type": "number"} 48 }, 49 "required": ["sku", "name", "qty", "unit_price"] 50 } 51 } 52 }, 53 "required": ["order_id", "total", "currency", "items"] 54 } 55 } 56 } 57 58 prompt = ( 59 "Generate a realistic example order summary with 2–3 items. " 60 "Use USD as ISO currency code. Fill every required field. " 61 "The order id is 1234567890. " 62 "The total is 100. " 63 "The currency is USD. " 64 "The items are 100. " 65 "The unit price is 1." 66 ) 67 68 # ---- Chat Completions payload ---- 69 payload = { 70 "model": LLM_MODEL, 71 "messages": [ 72 {"role": "system", "content": "Return ONLY valid JSON matching the provided schema."}, 73 {"role": "user", "content": prompt}, 74 ], 75 "response_format": response_format, 76 } 77 78 resp = requests.post( 79 f"{LLM_API_ENDPOINT}/chat/completions", 80 headers=headers, 81 json=payload, 82 timeout=60, 83 ) 84 85 # Raw response 86 if not resp.ok: 87 print(resp.status_code, resp.text) 88 resp.raise_for_status() 89 90 data = resp.json() 91 92 # Simple parse of final JSON content 93 try: 94 content = ( 95 (data.get("choices") or [{}])[0] 96 .get("message", {}) 97 .get("content", "") 98 ) 99 parsed = json.loads(content) if content else None 100 except Exception: 101 parsed = None 102 103 print("\n=== Output ===") 104 print(json.dumps(parsed, indent=2) if parsed is not None else "None")
$ === Output === $ { > "currency": "USD", > "items": [ > { > "name": "Wireless Bluetooth Earbuds", > "qty": 40, > "sku": "WBE-001", > "unit_price": 1.0 > }, > { > "name": "USB-C Charging Cable (6ft)", > "qty": 35, > "sku": "UCC-002", > "unit_price": 1.0 > }, > { > "name": "Phone Stand - Adjustable", > "qty": 25, > "sku": "PSA-003", > "unit_price": 1.0 > } > ], > "order_id": "1234567890", > "total": 100.0 > }
| Practice | Description |
|---|---|
Use strict: true | Ensures output exactly matches your schema |
Set additionalProperties: false | Prevents extra fields in response |
Include all fields in required | Guarantees complete responses |
Add description to properties | Helps the model understand field purpose |
1 import json 2 from pydantic import BaseModel, ValidationError 3 4 class Person(BaseModel): 5 name: str 6 age: int 7 city: str 8 9 # Always validate model output 10 try: 11 content = response.choices[0].message.content 12 data = json.loads(content) 13 person = Person(**data) # Pydantic validation 14 except json.JSONDecodeError: 15 print("Model returned invalid JSON") 16 except ValidationError as e: 17 print(f"Schema validation failed: {e}")
strict: true for reliable schema adherencewith_structured_output handles validation automatically