Structured output
We can ask the model to return a structured output by specifying a response format.
The structured output will come as a TextPart
and require parsing into an object.
import { getModel } from "./get-model.ts";
const text = `Grandma's Classic Pancakes
These fluffy pancakes are quick to make and perfect for breakfast!
Ingredients (makes 8 pancakes):
1 cup all-purpose flour2 tablespoons sugar1 teaspoon baking powder1/2 teaspoon baking soda1/4 teaspoon salt3/4 cup buttermilk1/4 cup milk1 large egg2 tablespoons unsalted butter, melted
Butter or oil for cooking
Instructions:
In a large bowl, whisk together flour, sugar, baking powder, baking soda, and salt.In another bowl, mix buttermilk, milk, egg, and melted butter.Pour the wet ingredients into the dry and stir until just combined (batter will be lumpy—don’t overmix).Heat a skillet over medium heat and lightly grease with butter or oil.Pour 1/4 cup batter for each pancake. Cook until bubbles form on the surface, then flip and cook until golden brown.Serve warm with maple syrup, fresh fruit, or whipped cream.
Prep time: 10 minutesCook time: 15 minutesTotal time: 25 minutes
Tags: breakfast, easy, kid-friendly`;
const schema = { title: "Recipe", type: "object", properties: { title: { type: "string", description: "The name of the recipe.", }, description: { type: "string", description: "A short description of the recipe.", }, ingredients: { type: "array", description: "List of ingredients required for the recipe.", items: { type: "string", }, }, instructions: { type: "array", description: "Step-by-step instructions for preparing the recipe.", items: { type: "string", }, }, prep_time: { type: "string", description: "Preparation time (e.g. '10 minutes').", }, cook_time: { type: "string", description: "Cooking time (e.g. '15 minutes').", }, total_time: { type: "string", description: "Total time required (e.g. '25 minutes').", }, tags: { type: "array", description: "Keywords or categories for the recipe.", items: { type: "string", }, }, }, required: [ "title", "description", "ingredients", "instructions", "prep_time", "cook_time", "total_time", "tags", ], additionalProperties: false,};
const model = getModel("openai", "gpt-4o");
const response = await model.generate({ system_prompt: `You are a helpful assistant that extracts structured data from text according to a provided JSON schema.`, messages: [ { role: "user", content: [{ type: "text", text }], }, ], response_format: { type: "json", name: "recipe", schema, },});
const textPart = response.content.find((part) => part.type === "text");if (!textPart) { throw new Error("No text part found in the response");}
console.log(JSON.parse(textPart.text));
use dotenvy::dotenv;use llm_sdk::{LanguageModelInput, Message, Part, ResponseFormatJson, ResponseFormatOption};use serde_json::Value;
mod common;
#[tokio::main]async fn main() { dotenv().ok();
let model = common::get_model("openai", "gpt-4o");
let text = r"Grandma's Classic Pancakes
These fluffy pancakes are quick to make and perfect for breakfast!
Ingredients (makes 8 pancakes):
1 cup all-purpose flour2 tablespoons sugar1 teaspoon baking powder1/2 teaspoon baking soda1/4 teaspoon salt3/4 cup buttermilk1/4 cup milk1 large egg2 tablespoons unsalted butter, meltedButter or oil for cooking
Instructions:
In a large bowl, whisk together flour, sugar, baking powder, baking soda, and salt.In another bowl, mix buttermilk, milk, egg, and melted butter.Pour the wet ingredients into the dry and stir until just combined (batter will be lumpy—don't overmix).Heat a skillet over medium heat and lightly grease with butter or oil.Pour 1/4 cup batter for each pancake. Cook until bubbles form on the surface,then flip and cook until golden brown.Serve warm with maple syrup, fresh fruit, or whipped cream.
Prep time: 10 minutesCook time: 15 minutesTotal time: 25 minutes
Tags: breakfast, easy, kid-friendly";
let schema = serde_json::json!({ "title": "Recipe", "type": "object", "properties": { "title": { "type": "string", "description": "The name of the recipe." }, "description": { "type": "string", "description": "A short description of the recipe." }, "ingredients": { "type": "array", "description": "List of ingredients required for the recipe.", "items": { "type": "string" } }, "instructions": { "type": "array", "description": "Step-by-step instructions for preparing the recipe.", "items": { "type": "string" } }, "prep_time": { "type": "string", "description": "Preparation time (e.g. '10 minutes')." }, "cook_time": { "type": "string", "description": "Cooking time (e.g. '15 minutes')." }, "total_time": { "type": "string", "description": "Total time required (e.g. '25 minutes')." }, "tags": { "type": "array", "description": "Keywords or categories for the recipe.", "items": { "type": "string" } } }, "required": [ "title", "description", "ingredients", "instructions", "prep_time", "cook_time", "total_time", "tags" ], "additionalProperties": false });
let response = model .generate(LanguageModelInput { system_prompt: Some( "You are a helpful assistant that extracts structured data from text according to \ a provided JSON schema." .into(), ), messages: vec![Message::user(vec![Part::text(text)])], response_format: Some(ResponseFormatOption::Json(ResponseFormatJson { name: "recipe".to_string(), description: Some( "A structured recipe including title, description, ingredients, instructions, \ prep time, cook time, total time, and tags." .to_string(), ), schema: Some(schema), })), ..Default::default() }) .await .unwrap();
let text_part = response .content .into_iter() .find_map(|part| match part { Part::Text(text_part) => Some(text_part), _ => None, }) .unwrap();
let val: Value = serde_json::from_str(&text_part.text).expect("Invalid JSON response");
println!( "{}", serde_json::to_string_pretty(&val).expect("Failed to format JSON") );}
package main
import ( "context" "encoding/json"
llmsdk "github.com/hoangvvo/llm-sdk/sdk-go" "github.com/hoangvvo/llm-sdk/sdk-go/examples" "github.com/hoangvvo/llm-sdk/sdk-go/utils/ptr" "github.com/sanity-io/litter")
func main() { const text = `Grandma's Classic PancakesThese fluffy pancakes are quick to make and perfect for breakfast!
Ingredients (makes 8 pancakes):
1 cup all-purpose flour2 tablespoons sugar1 teaspoon baking powder1/2 teaspoon baking soda1/4 teaspoon salt3/4 cup buttermilk1/4 cup milk1 large egg2 tablespoons unsalted butter, melted
Butter or oil for cooking
Instructions:
In a large bowl, whisk together flour, sugar, baking powder, baking soda, and salt.In another bowl, mix buttermilk, milk, egg, and melted butter.Pour the wet ingredients into the dry and stir until just combined (batter will be lumpy—don’t overmix).Heat a skillet over medium heat and lightly grease with butter or oil.Pour 1/4 cup batter for each pancake. Cook until bubbles form on the surface, then flip and cook until golden brown.Serve warm with maple syrup, fresh fruit, or whipped cream.
Prep time: 10 minutesCook time: 15 minutesTotal time: 25 minutes
Tags: breakfast, easy, kid-friendly`
type Output struct { Title string `json:"title"` Description string `json:"description"` Ingredients []string `json:"ingredients"` Instructions []string `json:"instructions"` PrepTime string `json:"prep_time"` CookTime string `json:"cook_time"` TotalTime string `json:"total_time"` Tags []string `json:"tags"` }
// You can use libraries like invopop/jsonschema to generate JSON schema from Go struct // instead of defining it manually like below. schema := llmsdk.JSONSchema{ "title": "Recipe", "type": "object", "properties": map[string]any{ "title": map[string]any{ "type": "string", "description": "The name of the recipe.", }, "description": map[string]any{ "type": "string", "description": "A short description of the recipe.", }, "ingredients": map[string]any{ "type": "array", "description": "List of ingredients required for the recipe.", "items": map[string]any{ "type": "string", }, }, "instructions": map[string]any{ "type": "array", "description": "Step-by-step instructions for preparing the recipe.", "items": map[string]any{ "type": "string", }, }, "prep_time": map[string]any{ "type": "string", "description": "Preparation time (e.g. '10 minutes').", }, "cook_time": map[string]any{ "type": "string", "description": "Cooking time (e.g. '15 minutes').", }, "total_time": map[string]any{ "type": "string", "description": "Total time required (e.g. '25 minutes').", }, "tags": map[string]any{ "type": "array", "description": "Keywords or categories for the recipe.", "items": map[string]any{ "type": "string", }, }, }, "required": []string{ "title", "description", "ingredients", "instructions", "prep_time", "cook_time", "total_time", "tags", }, "additionalProperties": false, }
model := examples.GetModel("openai", "gpt-4o")
response, err := model.Generate(context.Background(), &llmsdk.LanguageModelInput{ SystemPrompt: ptr.To("You are a helpful assistant that extracts structured data from text according to a provided JSON schema."), Messages: []llmsdk.Message{ llmsdk.NewUserMessage( llmsdk.NewTextPart(text), ), }, ResponseFormat: llmsdk.NewResponseFormatJSON("recipe", nil, &schema), })
if err != nil { panic(err) }
var textPart *llmsdk.TextPart for _, part := range response.Content { if tp := part.TextPart; tp != nil { textPart = tp break } }
if textPart == nil { panic("no text part found in the response") }
var output Output if err := json.Unmarshal([]byte(textPart.Text), &output); err != nil { panic(err) }
litter.Dump(output)}