Skill Runtime V2.3
September 4, 2026 · View on GitHub
本轮只改进
pentester_skill_search的检索精度(在 allowedSkillIds 内)。 未改 Builtin topology / grants / search / load contract(§28/§31/§35)。 Search 保持 deterministic,不调用 runtime LLM(§20)。
1. Baseline(V2.2)
Recall@3 0.545
Recall@5 0.693
Recall@8 0.772
MRR 0.440
MustRecall miss 0.228
Duplicate rate 0.881 (同 family 出现 2+ 次)
Retrieval Failure 3 / 71
根因:简单 score += x 权重 + 弱 relation 加分,无法捕捉语义等价
(brute force ≈ fuzzing、Entra ID ≈ Azure AD、tool 名变体),也没有真正的去重。
2. Benchmark Metric Fixes
统一 failure taxonomy(§2),由 scripts/benchmark-lib.mts 单一实现,runner 与报告复用:
GRANT_FAILURE 正确 skill 不在 allowedSkillIds
RETRIEVAL_FAILURE 在 allowed 但未进入 Top-K
RANKING_FAILURE 进入结果但排名 > 3
ROUTING_FAILURE 实际 owner agent ≠ 期望 agent
GOLD_LABEL_ERROR skill 是 defensive/forensics,本就不该 offensive 召回
修复了两处口径不一致:
- §13 的 "Retrieval Failure = 3" vs §17 的 "= 2" → 实为 graphql 出现 2 个 query,skill 级 2 个、pair 级 3 个;现统一 skill 级。
- Duplicate 从「同 family」改为「relation=overlap/equival 语义重复」——因为「同 family 的 general+specialist+tool」 是 §16 期望的互补组合,不是冗余;V2.2 的 0.881 把正确召回误判为重复。
3. Query Normalization
新模块 src/query-normalizer.ts:
normalizeSkillQuery(query): NormalizedSkillQuery
// { original, normalized, tokens, expandedTokens, detectedTools, detectedTechniques, detectedPlatforms }
- 连续 token(1~4 gram)最长短语优先匹配 alias。
- 单复数归一化(
ies→y、尾s去):tickets→ticket、directories→directory。 - 展开结果同时产出 tokenize 形式(供 BM25)与 norm 形式(供 structured 精确命中)。
4. Alias Architecture
build-time 生成 lib/generated/skill-search-aliases.json(scripts/build-skill-aliases.mjs):
generated aliases(从 cards tags/tools 提取变体)
∪
curated aliases(156 terms + 42 tools,行业同义词 + 自然语言映射)
覆盖:azure ad ↔ entra id ↔ aad、brute force ↔ fuzzing、kerberoasting ↔ tgs ↔ service account ticket、
adcs ↔ esc8 ↔ esc1、GetUserSPNs ↔ impacket、bloodhound ↔ sharphound、ROADtools ↔ roadrecon ↔ roadtx、
ssrf ↔ internal request、xss ↔ javascript 等。
关键设计:alias 值为原始 term(可分词),运行时展开成 tokenize + norm 双形式,使 「Azure AD」能通过 BM25 命中 summary 含「Entra ID」的 skill(而不仅是 tag 精确相等)。
5. Candidate Generation(召回与精排分离,§12)
第一阶段(高 recall):exact + structured + field-weighted BM25 → 候选池 top 25
第二阶段(高 precision):MMR-style selection loop → Top 3~8
权限模型不变:候选生成一开始就限定 allowedSkillIds(§3),绝不从全局 961 召回再过滤。
6. Field-weighted BM25
小型 deterministic BM25(k1=1.2, b=0.75),corpus 仅 allowed pool(通常 20~120 docs)。 字段权重(§11 name/technique/tools 高,summary 中,body 低):
id=3.0 techniqueTags=2.5 tools=2.5 capabilityTags=1.5 summary=1.2
familyIds=1.0 distinctiveFeatures=0.8 bodyText=0.4
IDF 与平均文档长度针对当前 allowed pool 计算(非全局)。
7. Structured Ranking
可解释 score 组件(§10):exact / structured / lexical / semantic / assignment / relation / redundancyPenalty / final。
精确命中优先级(§9):exact canonical id > technique tag > tool > capability > family > target > summary lexical > body fallback。SKILL.md 某处碰巧出现的词不会击败 techniqueTags 精确命中 (结构化 ×4 vs body ×0.4 权重 + BM25 字段加权)。
8. Relation Diversification(MMR)
selection loop:每选一个 skill,对剩余候选叠加冗余惩罚(§13/§14/§15):
equivalent 0.8 overlap 0.5 workflow-variant 0.25 specializes -0.15 generalizes -0.1
tool-specific(query 命中 tool 时鼓励) technique-specific(命中 technique 鼓励) complementary(coverage bonus)
并叠加 family 冗余惩罚(primary family 0.45 / secondary 0.2)——因为 relation graph 中同 family 的 specialist 之间多是 complementary 而非 overlap,仅靠 relation 边不足以去重。
Duplicate(overlap 语义)从 0.881 → 0.366(§27 目标 ≤0.40 达标)。
9. recommendedLoad Selection
从 Top-K 选 1~4 个(§17),排除已加载(§23),组合策略:
最高分(general/最相关)→ 不同 family coverage → 补齐(允许同 family)
不再 results.slice(0,3),而是体现 general/specialist/tool 的 capability coverage。
10. Semantic Retrieval Experiment
Evaluated = YES,Enabled = NO(§18/§19):
- DSH 无 embedding API(
ctx.skills的 "embedded" 指内嵌 skill,非向量);仓库无 embedding 依赖。 - deterministic 已达标(见 §11/§13),引入 embedding 需新增依赖 + build-time 向量 + 模型文件随 npm 发布, 违反 §19「禁止为 961 docs 引入 vector DB / daemon / external service」。
- 结论 = §19 Option 3:只用 alias + BM25 + structured + relations,由 benchmark 证明足够。
11. A/B Results
| Pipeline | Recall@5 | Recall@8 | MRR | miss |
|---|---|---|---|---|
| V2.2 baseline(旧 score + 弱 relation) | 0.693 | 0.772 | 0.440 | 0.228 |
| V2.3 full(alias + BM25 + structured + MMR) | 0.941 | 0.99 | 0.777 | 0.01 |
alias 的独立贡献(paraphrase,agent-scoped):
alias OFF: Recall@5 0.76, stability 0.3
alias ON : Recall@5 1.00, stability 1.0
12. Regression Results(§28)
scripts/benchmark-lib.mts 内置 8 个 known regression:
passed 8/8
PASS GraphQL hidden parameters
PASS WAF bypass
PASS Entra ID / Azure AD
PASS Azure AD device code phishing
PASS brute force directory / fuzzing
PASS directory fuzzing
PASS ROADtools token acquisition
PASS request service tickets for offline cracking
13. Paraphrase Stability
`analysis/skill-runtime-benchmark/paraphrase-benchmark.json$:10 \text{intents} \times 5 表达 = 50 \text{queries}。
$``text alias ON: Recall@5 = 1.00, stability = 1.0(10/10 intents 全部表达稳定召回)
覆盖 acronym(ADCS/SSRF/XSS)、旧/新名(Entra ID/Azure AD)、tool alias(GetUserSPNs/impacket)、
缩写、技术同义词、自然语言描述。
## 14. Custom Skill Behavior
Custom 无 Curation Card,继续 fallback name/description/body(§22),但已纳入 BM25 + alias 归一化;
user-explicit grant 保持轻量 boost(+0.5,不强制胜出)。
## 15. Performance
BM25 与 selection 均为 O(pool × fields × queryTokens)。allowed pool 通常 20~120 docs,
单次 search < 1ms 量级;无向量计算、无外部服务、无 runtime LLM 调用,latency 与 cost 不增加。
## 16. Selected Final Algorithm
`analysis/skill-search-v2.3/selected-ranking-config.json`:
```text
alias + structured + field-weighted-BM25 + relation/family-aware MMR selection
最低复杂度达到主要质量目标(§34),未启用 semantic。
17. Tests
新增 test/skill-search-v2.test.ts(18 个)+ 保留 test/skill-runtime.test.ts:
alias normalization / tool & technique alias / BM25 字段加权 / structured exact /
allowedSkill 过滤 / relation redundancy / recommendedLoad 组合 / custom skill /
paraphrase stability / known regression
pnpm test: 408 pass / 0 fail
pnpm run typecheck: PASS
18. Remaining Failure Cases
GRANT_FAILURE 5 → mobile/binary/phishing 边界(非默认 PTES,不属 Search 问题,§32 不处理)
ROUTING_FAILURE 7 → domain 映射 ground truth 粗导致的合理语义差异(exploit→validation、subdomain→recon 等)
RANKING_FAILURE 3 → 3 个 mustRecall 排名第 4-8(不是 miss,是精排仍可提升)
GOLD_LABEL_ERROR 0
Global 101 query 中 1 个 miss(directory brute force with ffuf)是 alias 展开在全局 961 下引入
defensive 噪声;agent-scoped(真实权限模型)下 paraphrase 已验证召回。deterministic lexical 的语义
等价天花板已基本逼近;进一步突破需 semantic(本轮判定不必要)。
SKILL_RUNTIME_V2_3_COMPLETE
Builtin topology changed:
NO
Builtin grants changed:
NO
Search contract changed:
NO
Load contract changed:
NO
Benchmark Queries:
101
Paraphrase Queries:
50
Recall@3:
0.901
Recall@5:
0.941
Recall@8:
0.99
MRR:
0.777
MustRecall Miss Rate:
0.01
Duplicate Rate:
0.366
Complementary Coverage:
1.0
Paraphrase Stability:
1.0
Tool Exact Recall:
1.0
Technique Exact Recall:
1.0
Semantic Retrieval Evaluated:
YES
Semantic Retrieval Enabled:
NO
Selected Retrieval Pipeline:
alias + structured + field-weighted-BM25 + relation/family-aware MMR selection
Known Regression Cases Passed:
8/8
Tests:
408/408
Typecheck:
PASS
Ready for real PTES evaluation:
YES