CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/koog

Koog 1.0 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM

87

1.85x
Quality

88%

Does it follow best practices?

Impact

87%

1.85x

Average score across 45 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-15/

{
  "context": "Tests whether the agent configures both providers under the ai.koog.<provider> convention, routes through MultiLLMPromptExecutor instead of autowiring individual LLMClient beans, and reads keys from environment variables — fixing the autowiring antipattern the previous engineer left.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "Configures both providers under ai.koog.<provider>",
      "description": "application.yml has both ai.koog.openai and ai.koog.google blocks with api-key and enabled: true. Neither provider is configured under a different prefix or hand-rolled property",
      "max_score": 25
    },
    {
      "name": "Reads both keys from environment variables",
      "description": "Each api-key reads from a ${VAR} expansion (e.g., ${OPENAI_API_KEY}, ${GOOGLE_API_KEY}). Neither key is hardcoded as a literal in YAML",
      "max_score": 20
    },
    {
      "name": "Migrates service code from LLMClient to MultiLLMPromptExecutor",
      "description": "The service that previously autowired LLMClient is changed to autowire MultiLLMPromptExecutor instead. Does not keep both injections, does not introduce a separate per-provider bean wiring",
      "max_score": 30
    },
    {
      "name": "Routes by model at the call site",
      "description": "The service code selects the model (OpenAI vs Google) at the call site by passing llmModel = OpenAIModels.* or GoogleModels.* to AIAgent(...). MultiLLMPromptExecutor routes based on which provider's models the call references",
      "max_score": 15
    },
    {
      "name": "Does not introduce a custom @Bean LLMClient override",
      "description": "Does not declare a @Bean @Primary LLMClient — the autoconfig handles the standard case; an override is only needed for custom transports/retry/etc.",
      "max_score": 5
    },
    {
      "name": "Does not remove the starter dependency",
      "description": "Keeps ai.koog:koog-spring-boot-starter on the classpath — that's what powers the autoconfig",
      "max_score": 5
    }
  ]
}

evals

README.md

tile.json