Koog 1.3 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM
72
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Process steps in order. Do not skip ahead.
implementation("ai.koog:agents-features-opentelemetry:1.3.0")The umbrella koog-agents does not include observability — add it explicitly.
Proceed immediately to Step 2.
Use whichever backend the user named. If the user did not name one, default to OTLP. Do not block on a clarifying question.
Proceed immediately to Step 3. Step 3 writes the actual code to disk; do not stop at prose.
Write the modified agent construction and the dependency to disk — do not respond with prose only. Use explicit Path: labels (same convention as scaffold-agent):
Path: src/main/kotlin/com/example/Main.kt — modified agent construction (or whichever file contains the AIAgent(...) call)Path: build.gradle.kts — appended dependency lineCreate files if they don't exist.
Install inside the AIAgent(...) trailing lambda. The feature is multiplatform (#1942 in 1.0), so the common-code block stays portable; JVM-only knobs come in Step 4.
Langfuse:
import ai.koog.agents.core.agent.AIAgent
import ai.koog.agents.features.opentelemetry.feature.OpenTelemetry
import ai.koog.agents.features.opentelemetry.attribute.CustomAttribute
import ai.koog.agents.features.opentelemetry.integration.langfuse.addLangfuseExporter
import ai.koog.prompt.executor.clients.openai.OpenAIModels
import ai.koog.prompt.executor.model.PromptExecutor
fun telemetryAgent(executor: PromptExecutor) = AIAgent(
promptExecutor = executor,
llmModel = OpenAIModels.Chat.GPT4o,
systemPrompt = "You are a helpful assistant.",
) {
install(OpenTelemetry) {
setVerbose(true) // include available prompt, completion, and response metadata
addLangfuseExporter(
traceAttributes = listOf(
CustomAttribute("langfuse.session.id", System.getenv("LANGFUSE_SESSION_ID") ?: ""),
)
)
setShutdownOnAgentClose(true)
}
}OTLP (raw):
import ai.koog.agents.features.opentelemetry.integration.otlp.addOtlpExporter
install(OpenTelemetry) {
addOtlpExporter(endpoint = System.getenv("OTEL_EXPORTER_OTLP_ENDPOINT"))
}Weave / Datadog: the corresponding add<Backend>Exporter functions live in feature/opentelemetry/integration/<backend>/. Use the env-var pattern for keys.
Don't stack two backends — pick one. Stacking compounds traces and inflates cost without adding signal.
Proceed immediately to Step 4.
JVM-specific exporter overloads are members of
ai.koog.agents.features.opentelemetry.feature.OpenTelemetryConfig.
There is no OpenTelemetryConfigJvm class and no extension import for its members.
import ai.koog.agents.features.opentelemetry.feature.OpenTelemetryConfig
import io.opentelemetry.sdk.trace.export.SpanExporter
fun configureExporter(config: OpenTelemetryConfig, exporter: SpanExporter) {
config.addSpanExporter(exporter)
config.setShutdownOnAgentClose(true)
}setShutdownOnAgentClose(true) shuts down telemetry when the owning agent closes.
It does not register a JVM exit hook. Close the agent explicitly; coordinate
telemetry ownership when several agents share a configuration.
Koog 1.3 carries Google's cachedContentTokenCount into response metadata and
OpenTelemetry, and fixes signature-only Gemini reasoning parts in Langfuse traces.
CLI processes may not report complete token/cost metadata. Instrument application
actions separately when the required signal is outside Koog's agent events.
Proceed immediately to Step 5.
Koog emits these GenAI metrics out of the box (target your dashboards at these names):
gen_ai.client.token.usagegen_ai.client.operation.durationgen_ai.client.tool.countSpan attributes follow current OTel GenAI conventions: gen_ai.input.messages / gen_ai.output.messages (per-message span events were deprecated in 1.0).
If the user wants per-step structured logging on top (e.g., to stdout during development), pair this skill with handle-agent-events. OpenTelemetry is for production signal; events are for development surface.
Finish here.
.tessl-plugin
skills
add-observability
add-persistence
references
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
references
test-koog-agents
trace-agent-internals
use-agent-skills
references
use-attachments
use-cli-agents
use-functional-agent
use-llm-node-variants
use-planner
wire-a2a
wire-acp-server
wire-ktor-server
wire-mcp-server
wire-spring-boot