Adding RAG to a Vercel Eve Agent with Upstash Redis Search
Vercel recently announced Eve, a framework for building agents. We used it to build a demo, Ask HackerNews, that answers questions about HackerNews from real data.
The agent uses retrieval-augmented generation (RAG). Instead of answering from the model's memory, it queries a search index and bases its answer on the results. The index is Upstash Redis Search, and the data is the HackerNews archive that also powers HackerNews Trends.
You can ask it things like "top stories about Rust", "what do people say about
remote work", or "average score of stories vs jobs". The code is on GitHub:
upstash/eve-example.

How the agent is built
Eve is filesystem-first. You write capabilities as files
under agent/, and Eve runs the model loop, persists each session, and serves the
agent over HTTP. We scaffolded the project with the Next.js template, which adds a
chat UI on top of the agent:
npx eve@latest init ask-hackernews --channel-web-nextjsSee the Next.js and Eve guide for
how the two fit together. Alternatively, you can also create a pure agent with
npx eve@latest init my-agent
The project layout looks like this:
agent/
agent.ts # model + runtime config
instructions.md # system prompt + Upstash Redis Search query reference
channels/eve.ts # HTTP channel
lib/hn-index.ts # Upstash Redis client + the `hn` index
tools/ # query.ts, count.ts, aggregate.ts
app/ # Next.js chat UI
next.config.ts # withEve(...)Under the tools directory, there are three tools the agent can use to talk with the
index: query, count, and aggregate. The next sections cover the data they search
and how the model drives them.
The data
The dataset is the same one behind HackerNews Trends,
our dashboard for HackerNews topic trends. Stories, comments, Ask/Show HN posts,
jobs and polls all live in a single Upstash Redis Search index named hn, along
with their titles, authors, scores and timestamps.
Upstash Redis Search
Upstash Redis Search adds full-text search and secondary indexes to Upstash Redis. You define a schema over your data and query it over HTTP, with filtering, sorting and aggregations.
A few query shapes cover what the agent needs:
// Full-text + filter + sort
await hn.query({
filter: { $and: [{ title: { $smart: "postgres" } }, { type: { $eq: "story" } }] },
orderBy: { score: "DESC" },
limit: 5,
});
// Count without fetching
await hn.count({ filter: { by: { $eq: "pg" } } }); // → { count: 10559 }
// Group items by type
await hn.aggregate({
aggregations: { by_type: { $terms: { field: "type" } } },
});$smart combines fuzzy, phrase and term matching in one operator, which works
well for natural-language input. There are more operators (facets, histograms,
percentiles, highlighting), but the basics handle most questions.
Letting the model write the queries
We didn't give the agent one fixed "search HackerNews" tool. It has three tools,
query, count, and aggregate, and each one passes a raw Upstash Redis Search
options object to the SDK:
// agent/tools/query.ts
export default defineTool({
description: "Run an Upstash Redis Search QUERY against the HackerNews index…",
inputSchema: z.object({
filter: z.any().optional(),
select: z.any().optional(),
limit: z.number().int().optional(),
orderBy: z.any().optional(),
/* … */
}),
async execute(options) {
return hn.query(options); // forwarded verbatim
},
});The query syntax and the index schema are in the agent's system prompt, so the model writes its own filters. Ask for the most upvoted stories about Postgres and it produces the following filter:
{
"$and": [
{ "type": { "$eq": "story" } },
{
"$or": [
{ "title": { "$eq": "Postgres" } },
{ "text": { "$eq": "Postgres" } },
]
}
]
}With the results, the agent is able to produce a correct response:

Conclusion
Two things made this easy. Vercel Eve took care of the agent loop, session state, and serving, so the app itself stayed small. And Upstash Redis Search has a query language expressive enough to hand straight to the model: full-text, keyword and numeric filters, boolean combinators, sorting, and server-side aggregations, all behind three generic tools.
The model can tailor the queries to whatever the user asks, and every answer stays grounded in real items it can cite. That expressive filtering is what makes Upstash Redis Search a strong fit for RAG.
Try it
The full source, including the agent, the tools, and the chat UI, is at
upstash/eve-example. To index your own
data, see the Upstash Redis Search docs
and create a database in the Upstash console.
