# Thursdays with Koog: PromptExecutor vs. AIAgent

> Source: <https://pac.commonsware.com/archive/thursdays-with-koog-promptexecutor-vs-aiagent/>
> Published: 2026-07-16 13:00:00+00:00

[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!
