In the previous chapter, Communication Channels, we gave our agent "ears" to hear messages and a "mouth" to speak. But right now, if a user says "Hello", the agent is just a hollow shell. It receives the message, but it doesn't know how to think or decide what to do.
This chapter introduces the Agent Loop. Think of this as the "Brain" or the "Conductor" of the entire application.
Imagine you ask a standard chatbot: "Check the weather in London and tell me if I need an umbrella."
A simple script might look like this:
But an AI model (LLM) cannot actually check the weather. It's just a text generator frozen in time. It might hallucinate: "It is raining in London" (even if it's sunny).
To solve this, we need a Loop that allows the agent to:
This cycle (Thinking β Action β Observation) is the heartbeat of PicoClaw.
At the highest level, the Agent Loop is an infinite process that waits for signals from the "Ears" (Channels).
It sits in the background, constantly asking: "Is there a new message?"
// pkg/agent/loop.go (Conceptual Simplified)
func (al *AgentLoop) Run(ctx context.Context) {
// Keep running forever until the program stops
for al.running.Load() {
// 1. Wait for a message from the Bus (Ears)
msg, ok := al.bus.ConsumeInbound(ctx)
if !ok {
continue
}
// 2. Process the message (The Brain)
response := al.processMessage(ctx, msg)
// 3. Send the result back (Mouth)
al.bus.PublishOutbound(response)
}
}
Explanation:
ConsumeInbound: This blocks and waits. As soon as a Telegram or Discord message arrives, it wakes up.processMessage: This is where the magic happens (we explain this next).PublishOutbound: Once the brain is done, the reply is sent back to the user.
When processMessage is called, we don't just send one prompt to the AI. We start a Conversation Loop.
This is often called the ReAct Pattern (Reasoning + Acting).
User: "Create a file named hello.txt."
write_file." (It doesn't talk to the user yet; it talks to the system).write_file("hello.txt").
Let's look at how PicoClaw implements this inner loop. This logic is found inside pkg/agent/loop.go.
We call this function runLLMIteration. It keeps spinning until the AI gives a final answer or we hit a limit (to prevent infinite loops).
We define a limit (e.g., 10 turns) so the bot doesn't get stuck arguing with itself.
// pkg/agent/loop.go (Simplified)
func (al *AgentLoop) runLLMIteration(ctx context.Context, messages []Message) (string, error) {
iteration := 0
// Keep looping while the AI wants to use tools
for iteration < al.maxIterations {
iteration++
// Ask the AI what to do
response, _ := al.provider.Chat(ctx, messages, al.tools)
// ... (Logic continues below)
}
}
When the response comes back from the AI, we check: Did it ask for a tool?
// If the AI didn't ask for a tool, it's a direct answer.
if len(response.ToolCalls) == 0 {
return response.Content, nil // We are done!
}
// If we are here, the AI wants to run tools.
// We append the AI's "thought" to the memory history.
messages = append(messages, Message{
Role: "assistant",
ToolCalls: response.ToolCalls,
})
Now we actually run the code the AI requested. Note how we feed the result back into messages. This updates the context for the next loop.
// Loop through all requested tools (e.g., creating 3 files at once)
for _, toolCall := range response.ToolCalls {
// 1. Execute the tool
result := al.tools.Execute(toolCall.Name, toolCall.Arguments)
// 2. Add the result to memory so the AI knows what happened
messages = append(messages, Message{
Role: "tool",
Content: result.Content,
ToolCallID: toolCall.ID,
})
}
// The loop now repeats! The AI sees the tool result and decides what to do next.
The Agent Loop doesn't work alone. It acts as the coordinator for several other systems:
In this chapter, we learned:
However, the Agent Loop is just a process manager. It is not "smart" on its own. It relies on an external brainβthe Large Language Model (LLM)βto make the actual decisions.
In the next chapter, we will learn how to plug in different brains (like OpenAI, Anthropic, or Local models).
Next: Chapter 3 - LLM Providers
Generated by Code IQ