Logo
Tutorials/Agent with RAG

5. A RAG agent that does math

In our third iteration of the agent we've combined the two previous agents, so we've defined both sumNumbers and a QueryEngineTool and created an array of two tools. The tools support both Zod and JSON Schema for parameter definition:

// define the query engine as a tool
const tools = [
  index.queryTool({
    metadata: {
      name: "san_francisco_budget_tool",
      description: `This tool can answer detailed questions about the individual components of the budget of San Francisco in 2023-2024.`,
    },
  }),
  tool({
    name: "sumNumbers",
    description: "Use this function to sum two numbers",
    parameters: z.object({
      a: z.number({
        description: "First number to sum",
      }),
      b: z.number({
        description: "Second number to sum",
      }),
    }),
    execute: ({ a, b }) => `${a + b}`,
  }),
];

You can also use JSON Schema to define the tool parameters as an alternative to Zod.

tool(sumNumbers, {
  name: "sumNumbers",
  description: "Use this function to sum two numbers",
  parameters: {
    type: "object",
    properties: {
      a: {
        type: "number",
        description: "First number to sum",
      },
      b: {
        type: "number",
        description: "Second number to sum",
      },
    },
    required: ["a", "b"],
  },
}),

These tool descriptions are identical to the ones we previously defined. Now let's ask it 3 questions in a row:

let response = await agent.run("What's the budget of San Francisco for community health in 2023-24?");
console.log(response);
 
let response2 = await agent.run("What's the budget of San Francisco for public protection in 2023-24?");
console.log(response2);
 
let response3 = await agent.run("What's the combined budget of San Francisco for community health and public protection in 2023-24?");
console.log(response3);

We'll abbreviate the output, but here are the important things to spot:

{
  toolCall: {
    id: 'call_ZA1LPx03gO4ABre1r6XowLWq',
    name: 'san_francisco_budget_tool',
    input: { query: 'community health budget 2023-2024' }
  },
  toolResult: {
    tool: QueryEngineTool {
      queryEngine: [RetrieverQueryEngine],
      metadata: [Object]
    },
    input: { query: 'community health budget 2023-2024' },
    output: 'The proposed Fiscal Year (FY) 2023-24 budget for the Department of Public Health is $3.2 billion
  }
}

This is the first tool call, where it used the query engine to get the public health budget.

{
  toolCall: {
    id: 'call_oHu1KjEvA47ER6HYVfFIq9yp',
    name: 'san_francisco_budget_tool',
    input: { query: 'public protection budget 2023-2024' }
  },
  toolResult: {
    tool: QueryEngineTool {
      queryEngine: [RetrieverQueryEngine],
      metadata: [Object]
    },
    input: { query: 'public protection budget 2023-2024' },
    output: "The budget for Public Protection in San Francisco for Fiscal Year (FY) 2023-24 is $2,012.5 million."
  }
}

In the second tool call, it got the police budget also from the query engine.

{
  toolCall: {
    id: 'call_SzG4yGUnLbv1T7IyaLAOqg3t',
    name: 'sumNumbers',
    input: { a: 3200, b: 2012.5 }
  },
  toolResult: {
    tool: FunctionTool { _fn: [Function: sumNumbers], _metadata: [Object] },
    input: { a: 3200, b: 2012.5 },
    output: '5212.5',
    isError: false
  }
}

In the final tool call, it used the sumNumbers function to add the two budgets together. Perfect! This leads to the final answer:

{
    message: {
      content: 'The combined budget of San Francisco for community health and public protection in Fiscal Year (FY) 2023-24 is $5,212.5 million.',
      role: 'assistant',
      options: {}
    }
}

Great! Now let's improve accuracy by improving our parsing with LlamaParse.

Edit on GitHub

Last updated on