Deep Agents
AgentContextOrchestratorRetrievalText2SQLToolbox

Skill Reminders

Automatically surface relevant skills per user query using BM25 text matching

Skill reminders match user message content against a catalog of skills and inject the top matches into the message. The LLM sees which skills are relevant and where to find their full documentation, enabling progressive disclosure — metadata upfront, full SKILL.md on demand.

skillsReminder

Creates an always-on user reminder that runs BM25 matching against the user's message content. Returns a ContextFragment you declare on the engine with engine.set(). The engine folds it into the last user message at save() time, so it re-classifies the message every turn.

import { user, skillsReminder } from '@deepagents/context';

const skills = [
  {
    name: 'deploy-helper',
    description: 'Assists with deployment workflows and CI/CD pipelines',
    path: '/skills/deploy-helper/SKILL.md',
  },
  {
    name: 'docker-expert',
    description: 'Docker containerization and multi-stage builds',
    path: '/skills/docker-expert/SKILL.md',
  },
];

engine.set(skillsReminder(skills, { topN: 3 }), user('deploy my app to production'));

await engine.save();

When the user's message matches skills, the reminder injects text like:

Relevant skills:
- deploy-helper (0.85): Assists with deployment workflows and CI/CD pipelines [/skills/deploy-helper/SKILL.md]
- docker-expert (0.42): Docker containerization and multi-stage builds [/skills/docker-expert/SKILL.md]

The reminder self-gates: when no skills match (score below threshold or unrelated content), its text resolver returns an empty string and the engine injects nothing.

Parameters

ParameterTypeDescription
skillsOrClassifierAvailableSkill[] | IClassifier<AvailableSkill>Array of skills or a custom classifier
options.topNnumberMax results to return (default: 5)
options.thresholdnumberMinimum score to include (default: 0)

AvailableSkill

Each skill needs three model-facing fields:

interface AvailableSkill {
  name: string;        // Skill name shown to the model
  description: string; // Description used for matching
  path: string;        // Model-visible path to SKILL.md
}

The application provisions and discovers skills, then passes the same array to skills() and skillsReminder(). See Skills for the ownership boundary.

Custom Classifiers

The classifier system is generic. skillsReminder accepts any IClassifier<AvailableSkill>, so you can replace BM25 with embeddings, an LLM call, or any other matching strategy.

import { user, skillsReminder, type IClassifier, type ClassifierMatch, type AvailableSkill } from '@deepagents/context';

const classifier: IClassifier<AvailableSkill> = {
  match(query, options) {
    // Your matching logic — embeddings, LLM-based, regex, etc.
    return [
      { item: mySkill, score: 0.99 },
    ];
  },
};

engine.set(skillsReminder(classifier, { topN: 5 }), user('anything'));

IClassifier Interface

IClassifier<T> is a generic interface exported from the package root. The skills module uses IClassifier<AvailableSkill> as its concrete type.

interface IClassifier<T> {
  match(query: string, options?: ClassifierOptions): ClassifierMatch<T>[];
}

interface ClassifierMatch<T> {
  item: T;
  score: number;
}

interface ClassifierOptions {
  topN?: number;
  threshold?: number;
}

BM25Classifier

The default classifier uses TF-IDF via tiny-tfidf. It builds a corpus from item names and descriptions, then ranks matches against the query. It works with any type that has name and description fields.

import { BM25Classifier } from '@deepagents/context';

const classifier = new BM25Classifier(skills);
const matches = classifier.match('optimize SQL queries', { topN: 3 });

When used with skillsReminder, this is equivalent to passing the skills array directly (which creates a BM25Classifier<AvailableSkill> internally).

You can reuse a single classifier instance across multiple skillsReminder() calls to avoid rebuilding the corpus.

Two predicates from the classifier module work with when-based conditional reminders. See Predicates for full documentation.

contentMatches

Fires when the user's message matches any of the given topics via BM25 scoring.

import { reminder, contentMatches } from '@deepagents/context';

engine.set(
  reminder('Consider using the deploy skill', {
    when: contentMatches(['deployment', 'CI/CD', 'production release']),
  }),
);

classifies

Fires when a classifier returns any results for the user's message. Works with any IClassifier<T>.

import { reminder, classifies, BM25Classifier } from '@deepagents/context';

const classifier = new BM25Classifier(skills);

engine.set(
  reminder('Check available skills for this task', {
    when: classifies(classifier, { topN: 3, threshold: 0.1 }),
  }),
);