optimizable Subgraph With Task
Creates an optimizable subgraph that performs a single task with a tunable instruction and bootstrappable few-shot demonstrations.
This is the optimization-aware counterpart of subgraphWithTask. Each optimizable subgraph acts as a "module" (in DSPy terms) whose instruction and demonstrations can be tuned by an optimizer without modifying the graph.
The three differences from subgraphWithTask:
Instruction resolution: the effective instruction is read from OptimizationArtifact in storage (falling back to optimizableInstruction), then passed to defineTask.
Demo injection: demonstrations from OptimizationArtifact are injected into the prompt after the task description, before the LLM request.
Trace export: intermediate messages are saved to storage before the prompt is discarded, enabling SubgraphTraceCollectionFeature to capture full execution traces.
If PromptOptimizationFeature is not installed, the subgraph uses optimizableInstruction and empty demonstrations.
Important: subgraph names must be globally unique within a strategy for optimization to work correctly. The OptimizationArtifact uses the subgraph name as a lookup key — duplicate names will cause incorrect instruction/demo assignment. If name is not provided, the property name is used (same convention as regular nodes and subgraphs in koog).
TODO: enforce global uniqueness of optimizable subgraph names within a strategy at construction time. Currently, duplicate names are not detected and silently cause incorrect optimization behavior.
Return
A delegate for use with Kotlin property delegation (by).
Parameters
The input type for the subgraph.
The output type for the subgraph.
Default instruction, overridable by OptimizationArtifact.
Optional subgraph name. If null, derived from the delegated property name. Used as the key for OptimizationArtifact lookup.
Strategy for selecting available tools.
Optional LLM model override.
Optional LLM parameters override.
Tool execution mode (sequential, parallel, single-run).
Max retries when the model doesn't call tools.
Optional post-processing of LLM responses.
When true, the subgraph starts with an empty conversation history.
How demos are inserted. Null inherits from PromptInsertionDefaults in storage.
Detail level for demos. Null inherits from PromptInsertionDefaults in storage.
Lambda that composes the user query from the resolved instruction and input. For fresh history, the resolved instruction is also placed as the system message separately, so demonstrations are sandwiched between the instruction and the query: system(instruction) → demos → user(defineTask(instruction, input)) → LLM response. The instruction is available in the lambda for convenience — if used, it will appear in both the system message and the user query (which is fine, it reinforces the instruction).