workshops/2025-05-17/sections/03-tool-loop/README.md
Now let's add a real agentic loop that can run the tools and get a final answer from the LLM.
First, lets update the agent to handle the tool call
src/agent.ts
}
-// right now this just runs one turn with the LLM, but
-// we'll update this function to handle all the agent logic
-export async function agentLoop(thread: Thread): Promise<AgentResponse> {
- const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
- return nextStep;
+
+
+export async function agentLoop(thread: Thread): Promise<string> {
+
+ while (true) {
+ const nextStep = await b.DetermineNextStep(thread.serializeForLLM());
+ console.log("nextStep", nextStep);
+
+ switch (nextStep.intent) {
+ case "done_for_now":
+ // response to human, return the next step object
+ return nextStep.message;
+ case "add":
+ thread.events.push({
+ "type": "tool_call",
+ "data": nextStep
+ });
+ const result = nextStep.a + nextStep.b;
+ console.log("tool_response", result);
+ thread.events.push({
+ "type": "tool_response",
+ "data": result
+ });
+ continue;
+ default:
+ throw new Error(`Unknown intent: ${nextStep.intent}`);
+ }
+ }
}
cp ./walkthrough/03-agent.ts src/agent.ts
Now, lets try it out
npx tsx src/index.ts 'can you add 3 and 4'
you should see the agent call the tool and then return the result
{
intent: 'done_for_now',
message: 'The sum of 3 and 4 is 7.'
}
For the next step, we'll do a more complex calculation, let's turn off the baml logs for more concise output
export BAML_LOG=off
Try a multi-step calculation
npx tsx src/index.ts 'can you add 3 and 4, then add 6 to that result'
you'll notice that tools like multiply and divide are not available
npx tsx src/index.ts 'can you multiply 3 and 4'
next, let's add handlers for the rest of the calculator tools
src/agent.ts
-import { b } from "../baml_client";
+import { AddTool, SubtractTool, DivideTool, MultiplyTool, b } from "../baml_client";
-// tool call or a respond to human tool
-type AgentResponse = Awaited<ReturnType<typeof b.DetermineNextStep>>;
-
export interface Event {
type: string
}
+export type CalculatorTool = AddTool | SubtractTool | MultiplyTool | DivideTool;
+export async function handleNextStep(nextStep: CalculatorTool, thread: Thread): Promise<Thread> {
+ let result: number;
+ switch (nextStep.intent) {
+ case "add":
+ result = nextStep.a + nextStep.b;
+ console.log("tool_response", result);
+ thread.events.push({
+ "type": "tool_response",
+ "data": result
+ });
+ return thread;
+ case "subtract":
+ result = nextStep.a - nextStep.b;
+ console.log("tool_response", result);
+ thread.events.push({
+ "type": "tool_response",
+ "data": result
+ });
+ return thread;
+ case "multiply":
+ result = nextStep.a * nextStep.b;
+ console.log("tool_response", result);
+ thread.events.push({
+ "type": "tool_response",
+ "data": result
+ });
+ return thread;
+ case "divide":
+ result = nextStep.a / nextStep.b;
+ console.log("tool_response", result);
+ thread.events.push({
+ "type": "tool_response",
+ "data": result
+ });
+ return thread;
+ }
+}
export async function agentLoop(thread: Thread): Promise<string> {
console.log("nextStep", nextStep);
+ thread.events.push({
+ "type": "tool_call",
+ "data": nextStep
+ });
+
switch (nextStep.intent) {
case "done_for_now":
return nextStep.message;
case "add":
- thread.events.push({
- "type": "tool_call",
- "data": nextStep
- });
- const result = nextStep.a + nextStep.b;
- console.log("tool_response", result);
- thread.events.push({
- "type": "tool_response",
- "data": result
- });
- continue;
- default:
- throw new Error(`Unknown intent: ${nextStep.intent}`);
+ case "subtract":
+ case "multiply":
+ case "divide":
+ thread = await handleNextStep(nextStep, thread);
}
}
cp ./walkthrough/03b-agent.ts src/agent.ts
Test subtraction
npx tsx src/index.ts 'can you subtract 3 from 4'
now, let's test the multiplication tool
npx tsx src/index.ts 'can you multiply 3 and 4'
finally, let's test a more complex calculation with multiple operations
npx tsx src/index.ts 'can you multiply 3 and 4, then divide the result by 2 and then add 12 to that result'
congratulations, you've taking your first step into hand-rolling an agent loop.
from here, we're going to start incorporating some more intermediate and advanced concepts for 12-factor agents.