Documentation
¶
Overview ¶
Package structout provides composable util functions for genkit enforcing structured output by tool-calling
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Output ¶
type Output[T any] struct { // Tool is the formatter tool exposed to the model. Its input schema is // generated from T. The tool body never runs — [Output.Middleware] // rewrites the response before genkit's tool loop can dispatch it. Tool *ai.ToolDef[T, any] // Middleware intercepts the model response after generation. When the // model returns the formatter tool as the only tool request in the turn, // the middleware marshals its input to JSON text and replaces // resp.Message so the tool loop exits cleanly. Pass to the Generate call // via ai.WithMiddleware. // // Caveats: // - Only the single-formatter case is rewritten. If the model emits // the formatter alongside other tool calls in the same turn, the // middleware passes through; the other tools run and the model // typically loops. Prompt the model to complete other tool use // first, then call the formatter on its own turn. // - Streaming is not supported. When a stream callback is present, // the middleware passes through unchanged and the caller must // handle the raw tool-request chunks themselves. // - Do not combine with ai.WithOutputSchema or a non-default output // format on the same request. [genkit.GenerateData] already // validates and unmarshals the synthesized text against T. Middleware ai.ModelMiddleware // Instruction is a system-prompt fragment that tells the model to call // Tool and emit its output JSON verbatim. Append it to a system message // of your choice; it references the tool by its registered name. Instruction string }
Output bundles the tool, middleware, and system-prompt instruction needed to coerce an LLM into producing a value of type T via tool-calling. It is the return value of Define.
The tool's input schema is derived from T; the middleware intercepts the model's tool call and rewrites the response to plain JSON text, so genkit.GenerateData can validate and unmarshal it into T.
Example:
type Jedi struct {
Name string `json:"name"`
Lightsaber string `json:"lightsaber" jsonschema:"enum=blue,enum=green,enum=purple"`
}
so := structout.Define[Jedi](g)
jedi, resp, err := genkit.GenerateData[Jedi](ctx, g,
ai.WithModelName("ollama/gemma4:e4b"),
ai.WithSystem("You are a Jedi master." + so.Instruction),
ai.WithPrompt("Introduce yourself."),
ai.WithTools(so.Tool),
ai.WithMiddleware(so.Middleware),
)
func Define ¶
Define registers a formatter tool for type T on g and returns an Output bundling the tool, a response-rewriting middleware, and a system-prompt instruction.
T should be a JSON-serializable struct; scalars and maps work but give the model a weaker schema to target.
Tools are memoized by reflect.Type: a second call to Define[T] with the same T returns the first registration. The memoization is process-global and is NOT scoped to a *genkit.Genkit instance — using multiple genkit instances in the same process with the same T will share the tool registered on whichever instance called Define[T] first.