optimizableSubgraphWithTask

inline fun <Input, Output> AIAgentSubgraphBuilderBase<*, *>.optimizableSubgraphWithTask(optimizableInstruction: String, name: String? = null, toolSelectionStrategy: ToolSelectionStrategy = ToolSelectionStrategy.ALL, llmModel: LLModel? = null, llmParams: LLMParams? = null, runMode: ToolCalls = ToolCalls.SEQUENTIAL, assistantResponseRepeatMax: Int? = null, responseProcessor: ResponseProcessor? = null, freshHistory: Boolean = false, fewShotPromptType: FewShotPromptType? = null, demonstrationFormat: DemonstrationFormat? = null, noinline defineTask: suspend AIAgentGraphContextBase.(instruction: String, input: Input) -> String): OptimizableSubgraphDelegate<Input, Output>

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:

  1. Instruction resolution: the effective instruction is read from OptimizationArtifact in storage (falling back to optimizableInstruction), then passed to defineTask.

  2. Demo injection: demonstrations from OptimizationArtifact are injected into the prompt after the task description, before the LLM request.

  3. 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

Input

The input type for the subgraph.

Output

The output type for the subgraph.

optimizableInstruction

Default instruction, overridable by OptimizationArtifact.

name

Optional subgraph name. If null, derived from the delegated property name. Used as the key for OptimizationArtifact lookup.

toolSelectionStrategy

Strategy for selecting available tools.

llmModel

Optional LLM model override.

llmParams

Optional LLM parameters override.

runMode

Tool execution mode (sequential, parallel, single-run).

assistantResponseRepeatMax

Max retries when the model doesn't call tools.

responseProcessor

Optional post-processing of LLM responses.

freshHistory

When true, the subgraph starts with an empty conversation history.

fewShotPromptType

How demos are inserted. Null inherits from PromptInsertionDefaults in storage.

demonstrationFormat

Detail level for demos. Null inherits from PromptInsertionDefaults in storage.

defineTask

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).