Koog 1.0 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM
71
88%
Does it follow best practices?
Impact
—
No eval scenarios have been run
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.
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