What scoring does
Scoring ranks entries in the pattern library (the per-machine store of past solutions described on The cross-project pattern library) against a task, so that only the most relevant few would be suggested. The arithmetic is deterministic: a script computes it the same way every time. One optional part uses an embedding model, explained below.
The scoring routine is part of the paqad-ai 1.91.1 code and its JavaScript interface (suggestPatternsForProject), but no command, hook or workflow in this release calls it. paqad-ai patterns list filters patterns; it does not score them.
Step 1: only patterns for the same kind of project are considered
Before scoring, patterns are filtered. A pattern is kept only if its stack_filter.domain matches the current domain (coding or content) and, when the project has frameworks, it shares at least one framework with the project.
Step 2: each remaining pattern gets a score
score = 0.25 × framework match
+ 0.35 × keyword match
+ 0.40 × semantic similarity
− 0.15 if the pattern is stale
| Part | How it is worked out |
|---|---|
| Framework match | The share of the project's frameworks that also appear in the pattern. A Laravel project and a Laravel pattern give 1. |
| Keyword match | The share of the task's keywords that appear anywhere in the pattern's problem text or tags, ignoring upper and lower case. The solution text is not searched. |
| Semantic similarity | How close in meaning the keywords are to the pattern, measured by comparing their vectors (lists of numbers produced by an embedding model). This part is 0 unless RAG is turned on with an embedding provider and the pattern vector index is present and valid. |
| Stale penalty | 0.15 is taken off when the pattern's created_at is more than 180 days ago. The result is also flagged is_stale. |
Without RAG the semantic part is always 0, so the highest possible score is 0.60.
Step 3: the best few are kept
Patterns scoring below 0.3 are dropped. The rest are sorted from highest to lowest and the top 3 are returned. Both numbers are defaults in the code; there is no setting for them in the project profile.
A worked example
A Laravel project, with the task keywords middleware, team and refund. A saved pattern has the framework laravel, a problem about team members opening invoices, and the tags middleware, teams and invoices. RAG is off.
- Framework match: 1 of 1 frameworks, so 0.25 × 1 = 0.25.
- Keyword match:
middlewareandteamappear,refunddoes not, so 0.35 × 2/3 ≈ 0.23. - Semantic similarity: 0, because RAG is off.
- Total: about 0.48, above 0.3, so the pattern is kept.
If the same pattern were 200 days old, 0.15 would come off, giving about 0.33. It would still be kept, marked as stale.
Machine arithmetic and model output
The framework match, keyword match, penalty, threshold and limit are plain arithmetic on stored text. The semantic similarity depends on the embedding model you configured for RAG, so its values change if you switch provider or model. Whether an AI tool then uses a suggested pattern well is model judgment.
Related housekeeping
The same 180-day age is the default for paqad-ai patterns prune, which permanently deletes patterns older than the threshold. Use --older-than <days> to change it. See the patterns command reference.