Skip to content
Forward Deployed

Forward Deployed
Lessons and contents
Learn

Research and competitive-intelligence agents

Source
From the RAG & Agents Engineering course
By
Sourav Banerjee
Last updated
9 Nov 2026

Report an issue

The project: research and market-brief agents

What you'll build

  • A research assistant that searches the web, reads the pages it finds and checks the current weather.
  • Budgeted tools that return at most three pages of 4,000 characters per search.
  • Conversation memory that lets a follow-up such as "And in Dubai?" refer to the earlier turn.
  • A competitive-intelligence analyst that returns a typed brief with a source URL per competitor and a field for data it could not find.
  • A grounding check in code that flags any cited URL the run never saw.

Lesson 1 of T8.3 guarded an agent that acts. These two agents only read. Their risk is a wrong claim rather than a wrong action. Both are create_agent agents from T7.2 with tools in the T7.1 style. The first answers general research questions. The second specialises the same idea into a retail analyst that watches clothing-store competitors in Bangalore. For Larkspur, the same build would watch competing hosts' pricing pages.

The project adds no new pattern. It shows what changes on the live web: each tool call costs tokens, the data changes between runs, and there is no fixed expected answer. Each check therefore compares the answer with the tool data from the same run.

Architecture

The two builds share one shape and differ in what comes out:

Diagram: User; create_agent prompt with today's date; Search and read 3 pages × 4,000 chars; Weather 7 fields kept; Typed brief analyst only; Grounding check in code; Checkpointer per threadDiagram: User; create_agent prompt with today's date; Search and read 3 pages × 4,000 chars; Weather 7 fields kept; Typed brief analyst only; Grounding check in code; Checkpointer per thread

Figure 1: Pieces of both builds. The weather tool and memory belong to the assistant, the typed brief and its check to the analyst.

Piece What it does Built on
Search-and-read tool Up to three search results, each page fetched in parallel, converted to text and cut to 4,000 characters. After 15 seconds it falls back to the snippet T7.1 tool schemas
Weather tool Current weather, trimmed from about 40 fields to 7. An unknown city returns a sentence T7.1 tool errors as messages
Tool-choice check Reads which tool the model would call for three questions (earnings, weather, arithmetic), running none T7.1 native tool calls
The assistant A prompt with today's date: search first, cite URLs, admit empty results T7.2 create_agent
Memory An in-memory checkpointer keyed by a thread id T4.4 checkpointers
Analyst persona A prompt for owners, marketers, location analysts and investors, and one search tool (five results)
Brief schema Area, audience, up to five competitors with an evidence URL each, opportunities, risks and data gaps T7.2 structured output
Grounding check Tests each evidence URL against every URL the search returned in the run

Table 1: The project's pieces.

Following a follow-up question

The assistant's memory test asks three questions on one thread. The last one only makes sense with the first two:

Turn Tool call What the thread holds after
1. How is the weather in Bangalore right now? Weather for Bangalore The question, the call, its result and the answer
2. And in Dubai? Weather for Dubai Both cities' results
3. Which of the two cities is hotter right now? None needed An answer drawn from turns 1 and 2

Table 2: Three turns on one thread. The data is live, and no values are fixed.

Ask turn 3 on a fresh thread and the agent cannot know which two cities you mean. It either asks, or picks two cities of its own and answers confidently. We call that a phantom referent: a follow-up answered about something the conversation never named.

The check after turn 3 reads the temperatures from the weather results stored in the thread, finds the hotter city and tests whether the answer's first line names it. It never trusts the model's own comparison.

The analyst's brief gets the same treatment for sources. To see the check fail, the notebook appends one invented competitor to a real brief:

Competitor entry Evidence URL In this run's search results
Entries from the agent's brief URLs the search returned Grounded
"Urban Threads Koramangala", busiest 6 to 9 pm on weekends An example.com footfall report Flagged as not from this run's searches

Table 3: The grounding check on a planted entry. A plausible line from memory has no URL the run saw.

Design choices worth copying

Choice Why
Today's date in the system prompt Without it, "most recent quarter" means the latest one in the training data
Budget every tool's output A full page can be tens of thousands of tokens. Three pages of 4,000 characters cap a search at 12,000
Return failures as text The agent adapts instead of crashing. Lesson 5 of T7.1 names the cost: error monitoring never sees these
Check tool choice before the loop One model call per question, and no tool runs
Make data gaps a field The original prompt asked for "example insights" when data was missing, an invitation to invent footfall figures. The field makes "no data" a visible answer
One evidence URL per claim, checked in code Separates claims from this run's searches from claims out of the model's memory

Table 4: Six choices and what each one protects against.

Limits

  • Live data. Answers differ on every run and there is no expected answer. Test behaviour instead: which tools were called, in what order, and whether the answer agrees with the tool results stored in the run.
  • A URL proves sight, not support. The grounding check shows the agent saw the page in this run. It does not show the page says what the brief claims. That needs a person, or a second check that quotes the page.
  • Memory lives in the process. The in-memory checkpointer loses every thread on restart.
  • Snippets are weaker evidence. A blocked or slow page leaves the agent a two-line snippet.

The assistant needs OpenAI, Tavily and OpenWeatherMap keys, and the analyst needs OpenAI and Tavily.

Run the notebooks

The code for this lesson is in these notebooks. Colab runs one in your browser: install the packages its first cell imports and set the API keys it reads. To run every notebook as written, clone the repository and use its uv environment.

Notebook GitHub Colab
Research assistant agent Open on GitHub Open in Colab
Competitive intelligence agent (optional) Open on GitHub Open in Colab

Key Takeaways

  • An agent over live sources needs budgets on what each tool returns and failures returned as readable text, or one call floods the context or ends the run.
  • Give the agent today's date and memory per thread, then check its answers against the tool data stored in the same run rather than its own summary.
  • Make missing data a field of the output and check every cited source against the URLs the run actually retrieved.

Check yourself

1. Why does the research assistant's system prompt include today's date?

The model does not know the date. Without it, "most recent quarter" means the most recent one in its training data, so the agent searches for an old quarter and reports it as current.

2. A brief lists a competitor whose evidence URL never appeared in the run's search results. What does the grounding check conclude, and what does it not prove?

It flags the entry as not from this run's searches. The URL came from the model's memory or was invented, and the claim needs checking by hand. A URL that passes proves only that the agent saw the page in this run, not that the page supports the claim.

3. A fresh thread receives the question of which of the two cities is hotter. What goes wrong, and what fixes it?

With no earlier turns, the agent asks which cities, or picks two of its own and answers confidently. A checkpointer with a thread id carries the Bangalore and Dubai weather results into the follow-up, and the check reads those stored results to confirm the answer.

Rate your confidence and keep notes on the module page.