{"slug": "thursdays-with-koog-promptexecutor-vs-aiagent", "title": "Thursdays with Koog: PromptExecutor vs. AIAgent", "summary": "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.", "body_md": "[Knosh](https://knosh.commonsware.com/) uses [Koog](https://docs.koog.ai) to execute prompts. Koog has a `PromptExecutor`\n\n, which executes prompts. Hence, it would seem like Knosh would use `PromptExecutor`\n\n, right?\n\nNope.\n\n`PromptExecutor`\n\nindeed executes prompts. It even does so in a one-shot fashion, the way Knosh operates. You hand `PromptExecutor`\n\na prompt, it passes the prompt along to the LLM model via its provider, and `PromptExecutor`\n\nhands back the response. Easy, peasy.\n\nHowever, that is pretty much *all* that `PromptExecutor`\n\ndoes. If you want anything else, you need to use something else.\n\nFor 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`\n\nor `Write`\n\nor `Bash`\n\n. You might think that tools are a dedicated communications channel between the LLM and the agent, completely independent from your prompt and its response.\n\nAlas, no.\n\nThe way tool calls work is:\n\nThat 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.\n\n`PromptExecutor`\n\ndoes none of that. In Koog, `AIAgent`\n\noffers that sort of high-level interface. For my Android developer audience: `PromptExecutor`\n\nis to OkHttp as `AIAgent`\n\nis to Retrofit. `AIAgent`\n\n*wraps* a `PromptExecutor`\n\nand handles multi-turn conversations, tool calls, and lots of other stuff that agents need.\n\nBecause Knosh needs tools, Knosh uses `AIAgent`\n\n.\n\nKnosh's `AIAgentFactory`\n\n[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\n\n`AIAgent`\n\nconstructor call:\n\n```\n    return AIAgent(\n      promptExecutor = promptExecutor,\n      llmModel = resolveModel(llmProvider, agentConfig.modelName, agentConfig.contextLength),\n      toolRegistry =\n        toolSet.build(agentConfig, commandPermissions, commandExternalDirectories, logFullToolCalls, allowedToolIds),\n      temperature = temperature ?: agentConfig.temperature,\n      maxIterations = maxIterations,\n      systemPrompt =\n        assembleSystemPrompt(\n          listOf(agentConfig.systemPrompt) +\n            loadAgentsMarkdown(\n              configDir = System.getProperty(\"user.home\").toPath() / \".config\" / \"knosh\",\n              workingDir = System.getProperty(\"user.dir\").toPath(),\n              fileSystem = fileSystem,\n            )\n        ),\n    )\n```\n\nKnosh uses `MultiLLMPromptExecutor`\n\nas its `PromptExecutor`\n\nimplementation. This wraps a map of `LLMProvider`\n\nobjects to `LLMClient`\n\nobjects — we covered those [a week ago](https://pac.commonsware.com/archive/thursdays-with-koog-providers-and-models/). The `LLMProvider`\n\nis a simple identifier of a provider (e.g., `LLMProvider.OpenAI`\n\n), while `LLMClient`\n\nknows things like the API key to use. `MultiLLMPromptExecutor`\n\nlets you configure all possible providers/clients that you wish to use.\n\nWe will explore many of those other `AIAgent`\n\nconstructor parameters in future issues. The two of importance for now is `promptExecutor`\n\nand `llmModel`\n\n. Those combine to let the `AIAgent`\n\nknow how to talk to the LLM:\n\n`PromptExecutor`\n\nwith the `LLModel`\n\n`MultiLLMPromptExecutor`\n\nuses that to identify what `LLMClient`\n\nto use, based on which `LLMProvider`\n\nthe `LLModel`\n\nis tied to`PromptExecutor`\n\nto execute a prompt, `MultiLLMPromptExecutor`\n\nuses the `LLMClient`\n\nTo have an `AIAgent`\n\nexecute a prompt, you call `run()`\n\n, passing in the desired prompt, perhaps just as a simple `String`\n\n. We will explore prompts and how Koog works with them in next week's issue!", "url": "https://wpnews.pro/news/thursdays-with-koog-promptexecutor-vs-aiagent", "canonical_source": "https://pac.commonsware.com/archive/thursdays-with-koog-promptexecutor-vs-aiagent/", "published_at": "2026-07-16 13:00:00+00:00", "updated_at": "2026-08-03 07:30:37.468094+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "artificial-intelligence"], "entities": ["Knosh", "Koog", "PromptExecutor", "AIAgent", "MultiLLMPromptExecutor", "Mark Murphy", "AIAgentFactory"], "alternates": {"html": "https://wpnews.pro/news/thursdays-with-koog-promptexecutor-vs-aiagent", "markdown": "https://wpnews.pro/news/thursdays-with-koog-promptexecutor-vs-aiagent.md", "text": "https://wpnews.pro/news/thursdays-with-koog-promptexecutor-vs-aiagent.txt", "jsonld": "https://wpnews.pro/news/thursdays-with-koog-promptexecutor-vs-aiagent.jsonld"}}