Thursdays with Koog: PromptExecutor vs. AIAgent Knosh, an open-source coding agent, uses Koog's AIAgent instead of PromptExecutor because PromptExecutor only executes one-shot prompts without handling tool calls or multi-turn conversations. Mark Murphy, the developer, explains that AIAgent wraps PromptExecutor to provide the high-level interface needed for tools, and Knosh's AIAgentFactory constructs the agent with a MultiLLMPromptExecutor and an LLM model. Knosh https://knosh.commonsware.com/ uses Koog https://docs.koog.ai to execute prompts. Koog has a PromptExecutor , which executes prompts. Hence, it would seem like Knosh would use PromptExecutor , right? Nope. PromptExecutor indeed executes prompts. It even does so in a one-shot fashion, the way Knosh operates. You hand PromptExecutor a prompt, it passes the prompt along to the LLM model via its provider, and PromptExecutor hands back the response. Easy, peasy. However, that is pretty much all that PromptExecutor does. If you want anything else, you need to use something else. For example, like any coding agent, Knosh has tools https://knosh.commonsware.com/tools/ . If you have used Claude Code, Codex, OpenCode, or the like, you will be used to seeing mentions of the agent using tools like Read or Write or Bash . You might think that tools are a dedicated communications channel between the LLM and the agent, completely independent from your prompt and its response. Alas, no. The way tool calls work is: That covers a single tool call in a one-shot prompt. The LLM could elect to call tools several times in succession -- the agent handles all that back-and-forth. In an interactive coding agent or any other "chatbot"-style interface, there are lots of prompts in a conversation -- the agent handles chaining all this stuff into the "context" that the initial prompt evolves into. PromptExecutor does none of that. In Koog, AIAgent offers that sort of high-level interface. For my Android developer audience: PromptExecutor is to OkHttp as AIAgent is to Retrofit. AIAgent wraps a PromptExecutor and handles multi-turn conversations, tool calls, and lots of other stuff that agents need. Because Knosh needs tools, Knosh uses AIAgent . Knosh's AIAgentFactory builds the AIAgent https://codeberg.org/commonsguy/knosh/src//tag/0.2.0/lib/knosh-agents/src/main/kotlin/com/commonsware/knosh/agents/AIAgentFactory.kt L209-L279 that a particular command uses. The core of that is the AIAgent constructor call: return AIAgent promptExecutor = promptExecutor, llmModel = resolveModel llmProvider, agentConfig.modelName, agentConfig.contextLength , toolRegistry = toolSet.build agentConfig, commandPermissions, commandExternalDirectories, logFullToolCalls, allowedToolIds , temperature = temperature ?: agentConfig.temperature, maxIterations = maxIterations, systemPrompt = assembleSystemPrompt listOf agentConfig.systemPrompt + loadAgentsMarkdown configDir = System.getProperty "user.home" .toPath / ".config" / "knosh", workingDir = System.getProperty "user.dir" .toPath , fileSystem = fileSystem, , Knosh uses MultiLLMPromptExecutor as its PromptExecutor implementation. This wraps a map of LLMProvider objects to LLMClient objects — we covered those a week ago https://pac.commonsware.com/archive/thursdays-with-koog-providers-and-models/ . The LLMProvider is a simple identifier of a provider e.g., LLMProvider.OpenAI , while LLMClient knows things like the API key to use. MultiLLMPromptExecutor lets you configure all possible providers/clients that you wish to use. We will explore many of those other AIAgent constructor parameters in future issues. The two of importance for now is promptExecutor and llmModel . Those combine to let the AIAgent know how to talk to the LLM: PromptExecutor with the LLModel MultiLLMPromptExecutor uses that to identify what LLMClient to use, based on which LLMProvider the LLModel is tied to PromptExecutor to execute a prompt, MultiLLMPromptExecutor uses the LLMClient To have an AIAgent execute a prompt, you call run , passing in the desired prompt, perhaps just as a simple String . We will explore prompts and how Koog works with them in next week's issue