Skip to main content
Upstash AgentKit builds AI agents on Upstash Redis: memory, conversation history, caching, and RAG, with no separate vector database. The semantic features run on Upstash Redis Search and its $smart fuzzy operator. @upstash/agentkit-ai-sdk is the Vercel AI SDK adapter — drop-ins for generateText / streamText. redis defaults to Redis.fromEnv(), so you import only from this package.
ImportFeature
createChatHistoryDurable chat history on Redis Search — save, list, and $smart-search a user’s transcripts.
createMemoryToolsrecall_memory + save_memory tools so the model reads and writes long-term memory.
createSearchToolssearch / aggregate / count tools over a Redis Search index (this is how you do RAG).
createRateLimitA configured Upstash Ratelimit to call before the model.
cachedToolsMemoize a map of AI SDK tools’ results in Redis.
AgentKit reads UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN from the environment by default. Pass your own @upstash/redis client as redis to any helper to override.

How to store chat history with the AI SDK

A Redis-backed ChatHistory<UIMessage>, the durable source of truth for your conversations. userId comes from your auth session; chatId is the useChat id that the client posts. Save the full transcript from your route’s onFinish:
To load a chat, take chatId from the page route and userId from the session, then seed useChat:
Each chat is one JSON doc at agentkit:chat:<userId>:<sessionId> (keyed per user, so two users can’t collide on a sessionId), indexed over userId + sessionId (filters) and userMessages + modelMessages ($smart fuzzy text); the raw messages array rides along unindexed. saveChat overwrites the whole array (no delta merge) — useChat sends the full conversation. Other methods: getChat / deleteChat ({ userId, sessionId }), listChats / searchChats ({ userId }).
Every method takes a single object; userId is required, non-empty, and may not contain :. Derive it from a verified server-side auth source — the subject/user id from your auth provider (Clerk, Auth.js/NextAuth, Supabase Auth, Auth0, …) — and never from a client-supplied header, query param, or body (read it from the session in your route). A chat can’t be read or overwritten under a different userId.

How to add agent memory with the AI SDK

recall_memory and save_memory tools so the model reads and writes its own long-term memory.
  • userId (required) — a string, or (input, options) => string.
  • redis — defaults to Redis.fromEnv().
  • topK — max memories recall returns.
  • minScore — BM25 relevance floor.
  • recallToolName / saveToolName — override the tool names.
userId is the only tenant boundary (required, non-empty, no :). Derive it from a verified server-side auth source (Clerk, Auth.js/NextAuth, Supabase Auth, Auth0, …) — never a client-supplied value. Memories are stored at agentkit:memory:<userId>:<id>.

How to add RAG with the AI SDK

search / aggregate / count tools over an Upstash Redis Search index; the model-facing descriptions are generated from your schema.
  • schema (required) — built with s from @upstash/redis.
  • redis — defaults to Redis.fromEnv().
  • indexName — defaults to "agentkit:search".
  • prefix — key prefix for indexed JSON docs (defaults to "<indexName>:").
  • defaultLimit — default page size for search (10).
The index is created (and waitIndexing-ed) reactively on first use — no setup step.

How to add rate limiting with the AI SDK

A configured Upstash Ratelimit. Call .limit(identifier) before the model and short-circuit when over the limit.
  • limiter (required) — e.g. Ratelimit.slidingWindow(20, "1 m") or fixedWindow(...).
  • redis — defaults to Redis.fromEnv().
  • prefix — base key prefix; keys are <prefix>:<identifier> (default agentkit:rateLimit).
There’s no model wrapper. Pass a per-user identifier to .limit() to throttle per user.

How to cache tools with the AI SDK

Memoize a map of AI SDK tools’ results in Redis. Each tool is cached under its map key, scoped to userId.
Pass tools built with the AI SDK’s tool() (so each keeps full input/output inference). Second arg:
  • userId (required) — a string, or (input, options) => string; scopes every entry to this user.
  • redis — defaults to Redis.fromEnv().
  • ttlSeconds — default per-result TTL for every tool.
Cache keys are agentkit:toolCache:<userId>:<toolName>:<hash-of-input> — the toolName is the map key, so you never pass a name yourself.

How to put it all together with the AI SDK

A single streamText route can wire every feature: rate limit first, then memory, search, and cached tools, persisting the whole conversation in onFinish:
A complete, runnable Next.js demo (useChat UI, chat sidebar with fuzzy search, inline tool calls) lives in examples/ai-sdk-demo.

AgentKit on GitHub

Source, packages, and the full example apps.

Vercel AI SDK

The AI SDK this adapter plugs into.