home / skills / sstobo / convex-skills / convex-agents-context

convex-agents-context skill

/convex-agents-context

This skill lets you tailor LLM context per call by customizing recent messages, search, and memory injection to improve relevance.

npx playbooks add skill sstobo/convex-skills --skill convex-agents-context

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.8 KB
---
name: "Convex Agents Context"
description: "Customizes what information the LLM receives for each generation. Use this to control message history, implement RAG context injection, search across threads, and provide custom context."
---

## Purpose

By default, the Agent includes recent messages as context. This skill covers customizing that behavior for advanced patterns like cross-thread search, memory injection, summarization, and filtering.

## When to Use This Skill

- Limiting context window to prevent token overflow
- Searching across multiple threads for relevant context
- Injecting memories or user profiles into every prompt
- Summarizing long conversations before continuing
- Filtering out sensitive or irrelevant messages
- Adding few-shot examples to guide LLM

## Configure Default Context Options

```typescript
const myAgent = new Agent(components.agent, {
  name: "My Agent",
  languageModel: openai.chat("gpt-4o-mini"),
  contextOptions: {
    recentMessages: 50,
    excludeToolMessages: true,
    searchOptions: {
      limit: 10,
      textSearch: true,
      vectorSearch: false,
    },
  },
});
```

## Override Context Per Call

```typescript
export const generateWithCustomContext = action({
  args: { threadId: v.string(), prompt: v.string() },
  handler: async (ctx, { threadId, prompt }) => {
    const result = await myAgent.generateText(
      ctx,
      { threadId },
      { prompt },
      {
        contextOptions: {
          recentMessages: 20,
          searchOptions: {
            limit: 5,
            textSearch: true,
            vectorSearch: true,
          },
        },
      }
    );

    return result.text;
  },
});
```

## Search Across Threads

```typescript
export const generateWithCrossThreadContext = action({
  args: { threadId: v.string(), userId: v.string(), prompt: v.string() },
  handler: async (ctx, { threadId, userId, prompt }) => {
    const result = await myAgent.generateText(
      ctx,
      { threadId, userId },
      { prompt },
      {
        contextOptions: {
          searchOtherThreads: true,
          searchOptions: {
            limit: 15,
            textSearch: true,
            vectorSearch: true,
          },
        },
      }
    );

    return result.text;
  },
});
```

## Custom Context Handler

Completely customize context:

```typescript
const myAgent = new Agent(components.agent, {
  name: "My Agent",
  languageModel: openai.chat("gpt-4o-mini"),
  contextHandler: async (ctx, args) => {
    const userMemories = await getUserMemories(ctx, args.userId);
    const examples = getExamples();

    return [
      ...userMemories,
      ...examples,
      ...args.search,
      ...args.recent,
      ...args.inputMessages,
    ];
  },
});
```

## Fetch Context Manually

Get context without calling LLM:

```typescript
import { fetchContextWithPrompt } from "@convex-dev/agent";

export const getContextForPrompt = action({
  args: { threadId: v.string(), prompt: v.string() },
  handler: async (ctx, { threadId, prompt }) => {
    const { messages } = await fetchContextWithPrompt(ctx, components.agent, {
      threadId,
      prompt,
      contextOptions: {
        recentMessages: 20,
        searchOptions: { limit: 10, textSearch: true },
      },
    });

    return messages;
  },
});
```

## Key Principles

- **Default context is sufficient**: Most use cases work with defaults
- **Search improves relevance**: Enable for long conversations
- **userId required for cross-thread**: Provide when searching multiple threads
- **Context handlers are powerful**: Use for memories, examples, special formatting
- **Recent messages take precedence**: Used after search in context order

## Next Steps

- See **rag** for knowledge base context injection
- See **fundamentals** for agent setup
- See **rate-limiting** for token management

Overview

This skill customizes what information the LLM receives for each generation. It lets you control message history, inject external context (memories, examples, RAG), search across threads, and apply custom filtering or summarization before sending prompts to the model.

How this skill works

It adjusts the agent's context pipeline by configuring contextOptions per agent or per call, or by providing a full contextHandler for bespoke assembly. You can limit recent messages, enable text or vector search across threads, inject persistent memories or few-shot examples, and fetch context without invoking the LLM.

When to use it

  • Prevent token overflow by limiting recent messages
  • Search multiple threads to surface relevant prior interactions
  • Inject user profiles, memories, or few-shot examples into every prompt
  • Summarize or filter long conversations before continuing a session
  • Add RAG knowledge or external documents as context for accurate answers

Best practices

  • Start with default context and only override when necessary
  • Use searchOptions (limit, textSearch, vectorSearch) to balance relevance and cost
  • Provide userId when enabling cross-thread search to scope results correctly
  • Prefer recentMessages for immediate context; use search for dispersed relevance
  • Implement a custom contextHandler for consistent memory or example injection

Example use cases

  • Limit recentMessages to avoid hitting token limits during long chats
  • Enable vectorSearch and textSearch to surface relevant past threads for personalized replies
  • Inject a user’s saved preferences and account details into every generation
  • Summarize a long thread into a short system message before continuing with a new prompt
  • Fetch context with fetchContextWithPrompt to inspect candidate messages without calling the model

FAQ

Do I have to change defaults for most use cases?

No. Default context works for most interactions. Override context only for specific needs like cross-thread search, memory injection, or token management.

What should I provide when searching across threads?

Include userId so cross-thread search can safely and accurately return user-scoped results; adjust searchOptions.limit to control returned volume.