Keep your AI research up to date
Some research you do once. Some you do again every month: competitors’ prices, vendors, open roles, funding rounds. An agent is good at each round. What’s awkward is everything between rounds: finding last month’s results, updating them rather than starting a new list, checking what changed, and trusting that the numbers you compared were the same ones you saw last time.
This page shows a way to do it with an agent and rho, with one example throughout: a competitor price list. rho keeps the table and its versions; the agent does the research. rho doesn’t run research by itself, check websites or run on a schedule: each round starts when you ask an agent that can search the web.
Start with a table worth maintaining
The first round decides how easy every later one is. Ask for columns that let you check a claim, not only state it:
You: Find the project-management tools for agencies and their plans. Save them in rho as research/competitors, with columns company, plan, monthly_price (in USD), source_url (the pricing page you read) and last_verified (today’s date).
Claude: Saved 5 rows as research/competitors. Version 1.
The result, with made-up companies:
| company | plan | monthly_price | source_url | last_verified |
|---|---|---|---|---|
| Acme Boards | Starter | 9 | acmeboards.example/pricing | 2026-10-01 |
| Acme Boards | Team | 19 | acmeboards.example/pricing | 2026-10-01 |
| Pinwheel | Basic | 12 | pinwheel.example/plans | 2026-10-01 |
| Taskly | Solo | 8 | taskly.example/pricing | 2026-10-01 |
| Ordo | Studio | 15 | ordo.example/pricing | 2026-10-01 |
source_urlsays where each price came from, so you, or the next agent, can check it.last_verifiedsays when it was last confirmed. A row that couldn’t be checked keeps its old date, so it stands out instead of looking current.companyandplantogether name a row. A company has several plans, so the company alone wouldn’t tell its rows apart. The next round updates rows by this pair.
Update existing research
A month later, in a new chat or another agent:
You: Check the prices in research/competitors again, by company and plan. Update the plans you can confirm, with today’s date, and add new ones. Leave any plan you can’t confirm as it is, and tell me which.
Claude: Updated 4 rows and added 1 (Fernway, Lite). I couldn’t reach Ordo’s pricing page, so Ordo Studio still says 2026-10-01. Version 2.
The agent writes with mode upsert and key_columns ["company", "plan"]: a row whose company and plan match is updated, a new pair is added, and the rest stay as they were. That’s what you want from a round that may not reach every source. A plan it couldn’t confirm keeps its last confirmed price, instead of being overwritten with a guess. And to list what needs a second look:
SELECT company, plan, last_verifiedFROM "research/competitors"WHERE last_verified < DATE '2026-11-01'An upsert never removes a row. When a plan is gone, either add a column such as status and mark it, which keeps it in the table, or have the agent write the whole list with mode replace. Either way, the version before still has it.
See what changed
Since the first round, one price went up and one plan is new:
| company | plan | previous_price | current_price | change |
|---|---|---|---|---|
| Acme Boards | Starter | 9 | 11 | changed |
| Fernway | Lite | 7 | added |
Every round is a version, and a query can read any of them: "research/competitors" is the latest, "research/competitors@1" the first. To compare them, join the two by the row’s key, so a price that changed shows as one row with both values, and a row that’s only in one version shows as added or removed:
SELECT coalesce(new.company, old.company) AS company, coalesce(new.plan, old.plan) AS plan, old.monthly_price AS previous_price, new.monthly_price AS current_price, CASE WHEN old.company IS NULL THEN 'added' WHEN new.company IS NULL THEN 'removed' ELSE 'changed' END AS changeFROM "research/competitors@1" AS oldFULL OUTER JOIN "research/competitors" AS new ON new.company = old.company AND new.plan = old.planWHERE old.monthly_price IS DISTINCT FROM new.monthly_priceORDER BY company, planIt compares prices only, so the four rows whose only change is last_verified don’t show. The table’s History in the rho app lists each version with who made it, its message, and the rows it added and removed; a diff there compares whole rows, so a row that changed shows as one removed and one added. For a question like “which prices changed”, the query above is the clearer answer.
Save and refresh the analysis
Questions come back too. Ask once, and save the answer as a table:
You: Save the plans under $10 a month as research/under_10.
The agent runs a query and saves its result with save_as:
SELECT company, plan, monthly_priceFROM "research/competitors"WHERE monthly_price < 10ORDER BY monthly_pricerho keeps the SQL with the table, and the version of research/competitors it read. After the first round, research/under_10 is Taskly Solo at 8 and Acme Boards Starter at 9.
After the second round, research/under_10 is out of date: the table it was made from has a newer version. rho says so wherever it’s read, until it’s refreshed. Then:
You: Refresh research/under_10.
Claude: Refreshed from research/competitors v1→v2. It’s now Fernway Lite at 7 and Taskly Solo at 8. Version 2; version 1 is kept.
A refresh runs the same SQL on the latest version of the table in rho. It doesn’t look anything up again on the web: new prices come from the next round of research, and the refresh carries them into the analysis. See Tables saved from a query.
What rho records, and what it can’t
rho records how the table got to where it is: each version’s rows, who wrote it and why, and for a saved analysis, its SQL and the versions it read. A figure an agent states from the table can come with a receipt that shows the query behind it.
It can’t record whether a price was right. That’s what source_url and last_verified are for: the evidence for each row, kept with the row. rho keeps what the agent wrote, exactly; checking it against the source is the agent’s job, or yours.
Restore and share
If a round gets something wrong, ask the agent to restore the version before. The restore is a new version, so the bad round stays in the history too, and nothing is lost.
To show the list to a colleague, make the table public and send the link: it opens in the browser, without signing in.
When something else fits better
If you need the answer once, ask in a chat. If people keep the list up to date by hand, a spreadsheet is the better tool. If you want the research done on a schedule without asking, that needs an agent that runs on a schedule; rho can be where it keeps the table.