Skill Discovery
SkillRouter uses vector-based semantic search to match natural-language queries to the most relevant skills in the registry, so your agents always find the right tool for the job.
How Vector-Based Discovery Works
Every skill registered in SkillRouter is embedded into a high-dimensional vector space using its name, description, and metadata. When your agent issues a discovery query, SkillRouter converts the query into the same vector space and performs an approximate nearest-neighbor search to find semantically similar skills.
This means your agents do not need to know exact skill names or identifiers. A query like "send a transactional email" will surface email-sending skills from providers like SendGrid, Resend, and Mailgun, ranked by how well they match the intent.
Embedding Index
Skills are embedded at registration time and stored in a vector index for sub-millisecond lookups.
Semantic Matching
Queries are matched by meaning, not keywords. Synonyms and paraphrases resolve to the same skills.
Quality Signals
Results are re-ranked using success rate, latency, and popularity to surface reliable skills first.
Using sr.discover(query)
The primary entry point for skill discovery is the sr.discover() method. Pass a natural-language query describing what you want to accomplish, and SkillRouter returns a ranked list of matching skills.
import SkillRouter from '@skillrouter/sdk';
const sr = new SkillRouter({ apiKey: process.env.SR_API_KEY });
// Basic discovery — returns top 5 matches by default
const results = await sr.discover("send a transactional email");
console.log(results);
// [
// { id: "sendgrid-send-email", score: 0.94, provider: "SendGrid", ... },
// { id: "resend-send-email", score: 0.91, provider: "Resend", ... },
// { id: "mailgun-send", score: 0.87, provider: "Mailgun", ... },
// ]Each result includes the skill metadata, a relevance score between 0 and 1, and the provider information. You can pass the top result directly to sr.execute() to run the skill immediately.
// Discover and execute in one flow
const [bestMatch] = await sr.discover("send a transactional email");
const result = await sr.execute(bestMatch.id, {
to: "user@example.com",
subject: "Welcome!",
body: "<h1>Thanks for signing up</h1>",
});Filtering by Category, Provider & Capability
You can narrow discovery results using filters. Filters are applied before the vector search, which reduces the candidate set and improves both speed and precision.
Category Filter
Restrict results to a specific skill category such as email, payments, storage, or web-browsing.
const results = await sr.discover("process a refund", {
category: "payments",
});Provider Filter
Limit results to skills from a specific provider. Useful when your organization has standardized on a particular service.
const results = await sr.discover("create a checkout session", {
provider: "stripe",
});Capability Filter
Filter by capability tags that describe what the skill can do, such as read, write, delete, or subscribe.
// Combine multiple filters
const results = await sr.discover("manage customer data", {
category: "crm",
provider: "hubspot",
capabilities: ["read", "write"],
limit: 10,
});Relevance Scoring & Ranking
Discovery results are ranked by a composite relevance score that blends multiple signals. The final score is a weighted combination of:
| Signal | Weight | Description |
|---|---|---|
| semantic_similarity | 0.60 | Cosine similarity between query and skill embeddings |
| success_rate | 0.20 | Historical execution success rate over the last 7 days |
| popularity | 0.10 | Number of unique agents using the skill recently |
| latency_score | 0.10 | Inverse of average execution latency (faster = higher) |
You can override the default ranking by providing a custom scoring function:
const results = await sr.discover("upload a file to cloud storage", {
rank: {
semantic_similarity: 0.5,
success_rate: 0.3,
latency_score: 0.2,
popularity: 0.0, // ignore popularity
},
});