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 ≈ fuzzingEntra 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→ticketdirectories→directory
  • 展开结果同时产出 tokenize 形式(供 BM25)与 norm 形式(供 structured 精确命中)。

4. Alias Architecture

build-time 生成 lib/generated/skill-search-aliases.jsonscripts/build-skill-aliases.mjs):

generated aliases(从 cards tags/tools 提取变体)

curated aliases(156 terms + 42 tools,行业同义词 + 自然语言映射)

覆盖:azure ad ↔ entra id ↔ aadbrute force ↔ fuzzingkerberoasting ↔ tgs ↔ service account ticketadcs ↔ esc8 ↔ esc1GetUserSPNs ↔ impacketbloodhound ↔ sharphoundROADtools ↔ roadrecon ↔ roadtxssrf ↔ internal requestxss ↔ 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

PipelineRecall@5Recall@8MRRmiss
V2.2 baseline(旧 score + 弱 relation)0.6930.7720.4400.228
V2.3 full(alias + BM25 + structured + MMR)0.9410.990.7770.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