Koog 1.0 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM
87
88%
Does it follow best practices?
Impact
87%
1.85xAverage score across 45 eval scenarios
Advisory
Suggest reviewing before use
Process steps in order. Do not skip ahead. This skill ends after Step 6 when the user has a runnable agent — do not chain into tool or MCP wiring; those are separate skills (add-tool, wire-mcp-server).
Ask the user, one question at a time:
If the user picks "other", confirm the factory exists in ai.koog:prompt-executor-llms-all (the umbrella). If not, plan to pull the specific prompt-executor-<provider>-client module — note this for Step 3.
Proceed immediately to Step 2 once all three are answered.
git init in the targetProceed immediately to Step 3.
build.gradle.ktsUse this template, substituting ${provider} placeholders:
plugins {
kotlin("jvm") version "2.3.10"
application
}
group = "com.example"
version = "0.1.0"
repositories { mavenCentral() }
dependencies {
implementation("ai.koog:koog-agents:1.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
testImplementation(kotlin("test"))
}
kotlin {
jvmToolchain(17)
}
application {
mainClass.set("com.example.MainKt")
}If the user picked a provider that requires a non-umbrella client artifact, add that dependency explicitly (e.g., implementation("ai.koog:prompt-executor-litert-client:1.0.0")).
Write settings.gradle.kts with rootProject.name = "<directory-name>" and a single include(":") is not needed for a flat project — leave it as just rootProject.name = ....
Proceed immediately to Step 4.
Main.ktPath: src/main/kotlin/com/example/Main.kt. Use the canonical 1.0 form — top-level AIAgent(...) factory, env-var API key, singleRunStrategy() is the default so no explicit strategy= parameter:
package com.example
import ai.koog.agents.core.agent.AIAgent
import ai.koog.prompt.executor.clients.openai.OpenAIModels
import ai.koog.prompt.executor.llms.all.simpleOpenAIExecutor
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
val apiKey = System.getenv("OPENAI_API_KEY")
?: error("Set OPENAI_API_KEY in your environment")
val agent = AIAgent(
promptExecutor = simpleOpenAIExecutor(apiKey),
llmModel = OpenAIModels.Chat.GPT4o,
systemPrompt = "You are a helpful assistant.",
)
val result = agent.run("Hello! What can you help me with?")
println(result)
}For Anthropic, swap simpleOpenAIExecutor → simpleAnthropicExecutor, OpenAIModels.Chat.GPT4o → AnthropicModels.Opus_4_7, and the env var name. For Google: simpleGoogleAIExecutor + GoogleModels.Chat.Gemini_2_5_FlashLite. For Ollama: simpleOllamaAIExecutor(baseUrl = "http://localhost:11434") and an OllamaModels.* entry; no API key needed.
Do NOT add strategy = singleRunStrategy() to the constructor — it's the default and listing it muddies the example. Add an explicit strategy = ... only when the user is overriding the default.
Proceed immediately to Step 5.
.gitignore:
.gradle/
build/
.idea/
*.iml
.DS_StoreREADME.md (minimal — one paragraph, the run command, and the env-var requirement):
# <project name>
A Koog 1.0 agent. Set `<PROVIDER>_API_KEY` and run `./gradlew run`.Proceed immediately to Step 6.
./gradlew --version to confirm the toolchain resolves. If Gradle isn't installed, point the user to https://gradle.org/install/ and finish here./gradlew build once. If it fails, surface the exact error and the line in build.gradle.kts it refers to — do not auto-fix; coordinate dependency overrides come from the user<PROVIDER>_API_KEY and run ./gradlew run to invoke the agent." Finish here.Do not chain into add-tool or wire-mcp-server — those are separate user invocations. If the user immediately asks for a tool or MCP after this, those skills handle it.
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
scenario-29
scenario-30
scenario-31
scenario-32
scenario-33
scenario-34
scenario-35
scenario-36
scenario-37
scenario-38
scenario-39
scenario-40
scenario-41
scenario-42
scenario-43
scenario-44
scenario-45
skills
add-observability
add-persistence
add-rag
add-structured-output
add-token-budgeting
add-tool
cache-llm-calls
define-prompt
domain-model-subtask-pipeline
references
enable-prompt-caching
handle-agent-events
manage-state
migrate-from-0-x
model-planner-subtasks
persist-chat-history
query-sql-from-agent
scaffold-agent
snapshot-and-restore
test-koog-agents
trace-agent-internals
use-attachments
use-functional-agent
use-llm-node-variants
use-planner
wire-a2a
wire-acp-server
wire-ktor-server
wire-mcp-server
wire-spring-boot