An AIAgentStrategy defines the execution logic of an AI agent. It encapsulates how the agent processes input to produce output, manages tool selection, and orchestrates the workflow. Strategies are the “brain” of the agent, determining the sequence of operations and decision-making logic.
All strategies implement the AIAgentStrategy interface:
interface AIAgentStrategy<TInput, TOutput, TContext : AIAgentContext> { /** * The name of the strategy */ val name: String /** * Executes the strategy with the given context and input */ suspend fun execute(context: TContext, input: TInput): TOutput?}
The most common strategy type, AIAgentGraphStrategy represents workflows as directed graphs of interconnected nodes:
public class AIAgentGraphStrategy<TInput, TOutput>( override val name: String, public val nodeStart: StartNode<TInput>, public val nodeFinish: FinishNode<TOutput>, toolSelectionStrategy: ToolSelectionStrategy)
Key Components:
Start Node: Entry point receiving agent input
Finish Node: Exit point producing agent output
Tool Selection Strategy: Determines which tools are available during execution
val strategy = strategy<UserInput, TripPlan>("planner-strategy") { // Storage for state val userPlanKey = createStorageKey<TripPlan>("user_plan") // Setup node val setup by node<UserInput, String> { userInput -> llm.writeSession { updatePrompt { system { +"Today's date is ${userInput.currentDate}" } } } userInput.message } // Subgraph for clarifying user intent val clarifyPlan by subgraphWithTask<String, TripPlan>( tools = userTools ) { message -> xml { tag("instructions") { +"Clarify the user's trip plan until all details are provided." } tag("message") { +message } } } // Save to storage val savePlan by node<TripPlan, TripPlan> { plan -> storage.set(userPlanKey, plan) plan } // Suggest detailed plan val suggestPlan by subgraphWithTask<TripPlan, TripPlan>( tools = weatherTools + mapsTools ) { userPlan -> xml { tag("instructions") { +"Suggest a detailed itinerary based on the user plan." } tag("user_plan") { +userPlan.toMarkdown() } } } // Connect nodes nodeStart then setup then clarifyPlan then savePlan then suggestPlan then nodeFinish}
For planning-based workflows that manage world state:
val plannerStrategy = AIAgentPlannerStrategy<WorldState, Plan>( name = "planner", planningLogic = { context, worldState -> // Generate plan based on world state generatePlan(worldState) }, executionLogic = { context, plan -> // Execute plan executePlan(plan) })
val key = createStorageKey<MyData>("my-data")// Storecontext.storage.set(key, myData)// Retrieveval data = context.storage.getValue(key)// Check existenceif (context.storage.contains(key)) { val data = context.storage.get(key)}
val mainStrategy = strategy<String, String>("main") { val subgraph1 by subgraph(createSubStrategy1()) val subgraph2 by subgraph(createSubStrategy2()) nodeStart then subgraph1 then subgraph2 then nodeFinish}fun createSubStrategy1() = strategy<String, String>("sub1") { val process by node<String, String> { /* ... */ } nodeStart then process then nodeFinish}
val clarify by subgraphWithTask<String, UserPlan>( tools = userTools + dateTools) { input -> // Prompt for this subgraph "Clarify the user's intent: $input"}
val strategy = strategy<String, String>("resilient") { val process by node<String, String> { input -> try { processInput(input) } catch (e: Exception) { context.environment.reportProblem(e) "Error: ${e.message}" } } nodeStart then process then nodeFinish}