Learn how to use beacon.interpretIntent() to match buyer intents against your product catalog using NLP-powered category detection and keyword scoring.
interpretIntent() in session handlers@aura-labs/beacon v0.2.0 or laterEstimated Time: ~20 minutes
When a buyer says “I need 50 ergonomic keyboards under $5000”, your Beacon needs to figure out which products in your catalog match. interpretIntent() handles this in two steps:
@aura-labs/nlp to check which information categories are present in the intent (what the buyer wants, how many, budget, delivery requirements, etc.)name, category, and tags fieldsThis is Layer 3 of the AURA three-layer NLP architecture:
Layer 1: @aura-labs/nlp Shared category detection + completeness checking
Layer 2: Scout SDK + Core Completeness gate (Scout) + authoritative parsing (Core)
Layer 3: Beacon SDK Domain-specific catalog matching (you are here)
Your Beacon performs presence detection only — semantic authority over intent meaning stays with Core (per the Neutral Broker architecture).
Create a catalog array with name, category, and tags for each item:
const catalog = [
{
name: 'Ergonomic Keyboard',
sku: 'KB-ERG-001',
category: 'keyboards',
tags: ['ergonomic', 'wireless', 'split'],
price: 89.99
},
{
name: 'Mechanical Keyboard',
sku: 'KB-MEC-001',
category: 'keyboards',
tags: ['mechanical', 'cherry-mx', 'backlit'],
price: 129.99
},
{
name: 'Gaming Mouse',
sku: 'MS-GAM-001',
category: 'mice',
tags: ['gaming', 'wireless', '16000-dpi'],
price: 69.99
},
{
name: 'Ultra-Wide Monitor',
sku: 'MN-UW-001',
category: 'monitors',
tags: ['ultrawide', '34-inch', 'curved', '144hz'],
price: 449.99
},
];
Tips for effective catalogs:
name values — they carry the highest matching weight (+20 per keyword match)category — it has the second-highest weight (+15 per match)tags — these provide breadth (+10 per match)Replace simple string matching with interpretIntent():
beacon.onSession(async (session) => {
const result = await beacon.interpretIntent(session.intent.raw, catalog);
console.log(`Intent: "${session.intent.raw}"`);
console.log(`Matches: ${result.matches.length}`);
console.log(`Confidence: ${result.confidence}`);
if (result.matches.length > 0) {
const top = result.matches[0];
console.log(`Top match: ${top.item.name} (score: ${top.score}, via: ${top.matchedOn.join(', ')})`);
await beacon.submitOffer(session.sessionId, {
product: { name: top.item.name, sku: top.item.sku },
unitPrice: top.item.price,
quantity: 1,
currency: 'USD',
deliveryDate: '2026-03-20',
});
}
});
interpretIntent() returns four fields:
matches — Scored Catalog Itemsresult.matches = [
{
item: { name: 'Ergonomic Keyboard', sku: 'KB-ERG-001', ... },
score: 60, // 0-100, higher is better
matchedOn: ['name', 'category', 'tags'] // Which fields matched
},
{
item: { name: 'Mechanical Keyboard', sku: 'KB-MEC-001', ... },
score: 15,
matchedOn: ['category']
}
];
Scoring weights:
confidence — Intent Completeness (0-1)How complete the buyer’s intent is. Higher values mean the buyer has specified more detail:
0.0 - 0.3 — Vague (“I need stuff”)0.3 - 0.6 — Partial (“I need keyboards”)0.6 - 0.8 — Good (“I need 50 ergonomic keyboards”)0.8 - 1.0 — Complete (“I need 50 ergonomic keyboards under $5000 by March 20”)categories — Tier 1 & Tier 2 Category Detectionresult.categories = {
// Tier 1 (core)
what: { present: true }, // What they want
how_many: { present: true }, // Quantity
what_kind: { present: true }, // Specifications
how_much_cost: { present: true }, // Budget
// Tier 2 (supplementary)
when_needed: { present: false },
where_deliver: { present: false },
quality_level: { present: false },
special_requirements: { present: false },
};
suggestions — Clarification QuestionsWhen categories are missing, suggestions contains questions you could ask:
result.suggestions = [
'When do you need this delivered?',
'Where should it be shipped?'
];
Set minimum score thresholds and use confidence to adjust offer aggressiveness:
beacon.onSession(async (session) => {
const result = await beacon.interpretIntent(session.intent.raw, catalog);
// Filter to meaningful matches
const strongMatches = result.matches.filter(m => m.score >= 30);
if (strongMatches.length === 0) return;
const top = strongMatches[0];
// Adjust pricing based on confidence
let price = top.item.price;
if (result.confidence > 0.7) {
// High-confidence intent — offer competitive pricing
price = top.item.price * 0.95;
}
await beacon.submitOffer(session.sessionId, {
product: { name: top.item.name, sku: top.item.sku },
unitPrice: price,
quantity: 1,
currency: 'USD',
deliveryDate: '2026-03-20',
});
});
interpretIntent() emits activity events automatically when called as a Beacon method:
// After processing sessions...
const summary = beacon.getActivitySummary();
console.log('Interpretation stats:', summary.interpretations);
// {
// total: 42, // Total interpretations run
// matched: 35, // Had at least one catalog match
// unmatched: 7, // No matches found
// failed: 0 // Provider errors (gracefully degraded)
// }
interpretIntent is also exported as a standalone function for use outside the Beacon class:
import { interpretIntent } from '@aura-labs/beacon';
// No Beacon instance needed — useful for testing or pre-processing
const result = await interpretIntent('I need ergonomic keyboards', catalog);
console.log(result.matches);
Note: The standalone function does not emit activity events (no activity logger is injected).
Check that your catalog items have relevant name, category, and tags fields. The matcher uses keyword overlap — if your product name is “KB-ERG-001” but the buyer says “keyboard”, there’s no overlap. Use human-readable names.
Confidence reflects intent completeness, not match quality. A buyer saying “keyboard” has low confidence because they haven’t specified quantity, budget, or specifications — but they may still match your catalog perfectly.
If you pass an LLM provider option and it fails, interpretIntent() degrades gracefully to regex-only category detection. Check the intent.interpretation_failed activity event for details.