r/SaaS•
AIBrahmi

Autonomous research multi agent Product Requirement Document (PRD) creation system - Day 2

Build In Public

Day 2: Building the Agent's Toolbox and Managing state

For our ResearchAgent, we need two primary capabilities:
- A tool to search the web.
- A tool to record its findings.

The Search Tool:
Leveraging Native Capabilities

Instead of complex web scraping, I'm tapping directly into Gemini's built-in function calling for Google Search.

The process:

- Define a google_types.Tool that enables the Google Search capability.
- Create a special llm_with_search instance that knows about this tool.
- Wrap this in a Python async function that the FunctionAgent* (e.g. Research Agent) can call.

*The FunctionAgent is a type of agent that uses an LLM provider's function/tool calling capabilities to execute tools.

from google.genai import types as google_types

1. Define the native tool:

google_search_tool = google_types.Tool(google_search=google_types.GoogleSearch())

2. Create a specialized LLM instance for it:

llm_with_search = GoogleGenAI(

model=" gemini-2.5-pro",

generation_config=google_types.GenerateContentConfig(tools=[google_search_tool]))

3. Wrap it in a Python function for the agent:

async def search_web(query: str) -> str: # ... logic to call llm_with_search ...

Managing state

Now for the most critical part: how does the WriteAgent get the notes from the ResearchAgent?

This is where LlamaIndex's state management shines. We create a record_notes tool that doesn't just return data. It writes to a shared "whiteboard" called the Context.

The ctx.store.edit_state() method is the key. It gives any tool secure write-access to the central workflow state.

Here’s the code:

# Any tool can get the context and edit the shared state

async def record_notes(ctx: Context, notes: str, notes_title: str) -> str:

async with ctx.store.edit_state() as state:

# 'state' is a direct reference to the workflow's state

if "research_notes" not in state:

state["research_notes"] = {}

state["research_notes"][notes_title] = notes

return "Notes recorded."

Notice how the ctx: Context is passed in. This is how LlamaIndex provides the tool with access to the shared state.

When this runs, it adds the notes to the research_notes dictionary in our main state object, ready for the next agent.

Now that our agents can act (search) and communicate (record_notes).

Posted Aug 5, 2025, 6:59 PM UTC

13
Loading comments…