Arjan van Wieringen
06/14/2025, 2:52 PMfun main() {
val config = ConfigFactory.load()
val kafkaService = KafkaService(config)
val toolRegistry =
ToolRegistry {
tools(KafkaToolSet(kafkaService).asTools())
}
val agent =
AIAgent(
executor = simpleOllamaAIExecutor(),
systemPrompt = "You a diagnostics agent. You can answer questions about the workings of systems provided to you via tools.",
llmModel = OllamaModels.Alibaba.QWEN_3_06B,
toolRegistry = toolRegistry,
maxIterations = 20,
strategy = singleRunStrategy(),
)
runBlocking {
val result = agent.runAndGetResult("Get me the consumer offsets and lag for all consumers")
}
}
This is the result:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<think>
Okay, the user is asking to get the consumer offsets and lag for all consumers. Let me check the tools available. There's a function called getConsumerOffsetsAndLags. The parameters are empty, so I don't need any arguments. I should call that function without any parameters. Let me make sure I'm using the right function name and structure the response correctly. Alright, I'll return the tool call as specified.
</think>
The model should support tools, so either I do not understand something or Koog does not handle the tool requests.Didier Villevalois
06/14/2025, 3:50 PMsingleRunStrategy()
is using requestLLM()
which is only keeping the first answer.
You have two options to try and make it work:
1. Prompt the model more to tell it to
◦ NOT share its thinking and reasoning
◦ NOT answer anything but the tool call, if it wants to make a tool call
2. Write your own strategy using nodeLLMRequestMultiple()
instead of nodeLLMRequest()
Arjan van Wieringen
06/14/2025, 4:11 PMDidier Villevalois
06/14/2025, 4:25 PMArjan van Wieringen
06/14/2025, 4:44 PMDidier Villevalois
06/14/2025, 4:48 PMsingleRunStrategy
.Arjan van Wieringen
06/14/2025, 4:51 PMDidier Villevalois
06/14/2025, 4:53 PMDidier Villevalois
06/14/2025, 4:57 PMsingleRunStrategy()
has to support Ollama from the get-go (by using normal LLM responses, i.e. lists of response messages, and not silently discarding all the messages but the first). You can see above that I am not the only one confused by that. Relying on non-standard things like tool-choice might not be a good idea on the simple examples in the documentation.Arjan van Wieringen
06/14/2025, 5:00 PMArjan van Wieringen
06/14/2025, 5:02 PMDidier Villevalois
06/14/2025, 5:08 PMimport ai.koog.agents.core.dsl.builder.*
import ai.koog.agents.core.dsl.extension.*
import ai.koog.prompt.message.*
private fun alternativeSingleRunStrategy() = strategy("alternativeSingleRunStrategy") {
val initialRequest by nodeLLMRequestMultiple()
val processResponses by nodeDoNothing<List<Message.Response>>()
val executeTools by nodeExecuteMultipleTools(parallelTools = true)
val toolResultsRequest by nodeLLMSendMultipleToolResults()
edge(nodeStart forwardTo initialRequest)
edge(initialRequest forwardTo processResponses)
edge(processResponses forwardTo executeTools onToolCallsPresent { true })
edge(processResponses forwardTo nodeFinish transformed { it.first() } onAssistantMessage { true })
edge(executeTools forwardTo toolResultsRequest)
edge(toolResultsRequest forwardTo processResponses)
}
infix fun <IncomingOutput, IntermediateOutput, OutgoingInput>
AIAgentEdgeBuilderIntermediate<IncomingOutput, IntermediateOutput, OutgoingInput>.onToolCallsPresent(
block: suspend (List<Message.Tool.Call>) -> Boolean
): AIAgentEdgeBuilderIntermediate<IncomingOutput, List<Message.Tool.Call>, OutgoingInput> {
return onIsInstance(List::class)
.transformed { it.filterIsInstance<Message.Tool.Call>() }
.onCondition { toolCalls -> toolCalls.isNotEmpty() && block(toolCalls) }
}
This is untested. I cooked it just for you.Arjan van Wieringen
06/14/2025, 5:11 PMArjan van Wieringen
06/14/2025, 5:13 PM<think>
Okay, so the user is asking if any of their consumers are lagging. The tool response shows consumer offsets and lag information for various groups. I need to parse this data to determine if any lag exists. Let me check each group's offset and lag. For example, in "accepted-testevent", the offset is 53 and lag is 0, which is good. Similarly, "rcr-perf-test" also has 0 lag. There are multiple entries with 0 lag, which suggests that all consumers are not lagging. Therefore, the answer should confirm that there is no lagging consumer based on the provided data.
</think>
From the consumer offset and lag data, **no consumers are lagging**. All entries show a lag of 0, indicating no lag in their processes.
This is greatDidier Villevalois
06/14/2025, 5:13 PMVadim Briliantov
06/15/2025, 2:02 PM