·4 min read

Adding RAG to a Vercel Eve Agent with Upstash Redis Search

Cahid Arda OzCahid Arda OzSoftware Engineer @Upstash
https://upstash.com/blog/ask-hackernews-with-vercel-eve

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.

Ask HackerNews landing page

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-nextjs

See 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 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:

A grounded answer with the underlying query tool call

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.

Looking for a managed Redis database?Upstash runs Redis as a serverless database - create one in seconds and pay only per request. Explore Upstash Redis →