Skip to content

真实数据:BiliDili 冷启动全记录

本章记录的是两次真实测试数据,两轮执行之间对调度和容错做了微调,所有数值均为原始日志直出,未做任何修正。 Alembic 的核心能力在于知识管理与 Guard 引擎,AgentRuntime 只是其中的自动化采集层。本章的目的不是宣传 Agent 有多强,而是如实展示当前冷启动的工程现状——哪些环节已经可用,哪些还有明显短板——为后续章节的 Recipe 审核和 Guard 规则生成提供数据基础。

19.1 项目画像

指标
项目BiliDili(iOS 客户端)
语言Swift
源文件124 个
SPM Packages4 个本地包
Alembic 版本3.3.9(两轮之间微调了调度与容错参数)
执行方式asd coldstart --wait --json

测试环境

两轮测试的运行环境完全一致(当天连续执行),如下:

环境项
LLM 模型gemini-3-flash-preview
API 接口Google AI Studio(付费层级 1)
上下文窗口1,048,576 input tokens / 65,536 output tokens
模型知识截止2025 年 1 月
运行时Node.js ≥ 22,macOS
两轮间隔当天连续运行(无重启清库)
实际 Token 费用第一轮:Input 8.26M × $0.10/M = $0.83,Output 0.138M × $0.40/M = $0.06,合计 $0.89;第二轮:Input 11.15M × $0.10/M = $1.12,Output 0.178M × $0.40/M = $0.07,合计 $1.19

关于 hard timeout 的说明:两轮中偶发出现 LLM "冻结" 现象(330s 等待后 0 tool calls),这是 gemini-3-flash-preview 预览版模型的已知不稳定行为,与付费层级无关。第一轮 architecture produce 和第二轮 design-patterns analyze 各出现一次——同一维度在另一轮中正常完成,说明这是随机事件而非系统性缺陷。

代码实体图谱

AST 分析在 Phase 2 完成后构建了完整的代码实体图谱:

实体类型数量
class214
method451
module20
protocol20
合计705
边类型数量占比
data_flow1,00341.4%
calls50520.8%
related40616.7%
conforms27111.2%
inherits1968.1%
depends_on431.8%
合计2,424

热点节点(入度最高):

DownloadTask.cancel        inDegree=38
Endpoint                   inDegree=32
ThreadSafeDictionary.contains   inDegree=32
ThreadSafeDictionary.removeAll  inDegree=32
ThreadSafeDictionary.removeValue inDegree=18

ThreadSafeDictionary 的三个方法在图谱中入度极高——这与 BiliDili 大量使用线程安全字典管理并发状态的实际架构吻合。

项目结构

BiliDili 的代码组织可以概括为“App 壳层在上,Sources/ 承载业务代码,Packages/ 提供复用基础能力”。对冷启动分析而言,真正需要展开的是 Sources/Packages/ 两层:

BiliDili/
├── BiliDili/                     # App 壳层,不展开
├── Sources/                      # 业务源码主层
│   ├── Core/
│   │   ├── PaginationKit/
│   │   └── ServiceKit/
│   ├── Features/
│   │   ├── Following/
│   │   ├── Home/
│   │   ├── LiveChat/
│   │   ├── Profile/
│   │   ├── VideoFeed/
│   │   └── VideoPlay/
│   └── Infrastructure/
│       ├── Account/
│       ├── Networking/
│       └── WebSocket/
└── Packages/                     # 4 个本地 SPM 包
    ├── AOXFoundationKit/
    ├── AOXNetworkKit/
    ├── AOXPlayer/
    └── AOXUIKit/

两层结构的真实分工

层级实际内容在项目中的职责Agent 分析重点
Sources/CoreFeaturesInfrastructure 三层承载业务功能、共享服务和基础设施实现,是主要的产品代码层Features/* 追到 Infrastructure/*Core/*,确认页面行为、数据流、错误处理和并发调用链
Packages/AOXFoundationKitAOXNetworkKitAOXPlayerAOXUIKit提供可复用基础能力,作为业务层下方的通用能力包分析底层网络、播放器、UI 组件、基础工具如何被 Sources/ 引用,以及跨层依赖是否稳定

这也是 concurrency-asyncperformance-optimization 两个维度 token 消耗较高的原因:Agent 不能只看 Sources/Features/* 的页面代码,还要继续追到 Sources/Infrastructure/*Packages/*,才能确认并发原语、网络封装和播放器能力的真实调用链。

第一轮 → 第二轮 关键引擎差异

两轮执行之间(同一 3.3.9 版本),对调度和容错参数做了以下微调:

改动项第一轮(优化前)第二轮(优化后)
Tier 调度3-Tier:2 + 2 + 105-Tier:2 + 3 + 3 + 3 + 3
Analyze 预算固定 maxIterations=24自适应 computeAnalystBudget(124)=34
SCAN→EXPLORE 阈值iter=3iter=2(提前 1 轮进入深度探索)
Produce 超时容错无 fast-retryfast-retry:超时 0 tool calls → retryBudget 自动重试
中止链无 abortSignalabortSignal:hard timeout 后立即中断 LLM 调用
反射频率3 Tiers → 3 reflections5 Tiers → 5 reflections
记忆蒸馏日志基础统计按维度 / 重要性分布 / 实体数 / 直方图

19.2 管线执行总览

第二轮时间线

整个 Bootstrap 从 05:46 UTC06:25 UTC,总耗时 2,176 秒(≈36.3 分钟)

05:46:49  Phase 0-4: 结构收集 + AST + Guard 审计
05:46:49  ── Tier 1/5 ── [architecture, swift-objc-idiom]
05:52:01  ── Tier 2/5 ── [coding-standards, design-patterns, networking-api]
06:00:21  ── Tier 3/5 ── [error-resilience, concurrency-async, data-event-flow]
06:07:46  ── Tier 4/5 ── [ui-interaction, testing-quality, security-auth]
06:15:16  ── Tier 5/5 ── [performance-optimization, observability-logging,
                           agent-guidelines]
06:23:04  Memory Consolidation (293ms) + Report
06:23:05  Cursor Delivery (26ms): 13 rules + 6 topics + 5 skills + 1 agent
06:25:13  Wiki Generation (8 files, 8 AI-enhanced)

对比第一轮时间线:

03:48:11  Phase 0-4: 结构收集 + AST + Guard 审计
03:48:11  ── Tier 1/3 ── [architecture, swift-objc-idiom]
04:09:00  ── Tier 2/3 ── [coding-standards, design-patterns]
04:13:28  ── Tier 3/3 ── [其余 10 个维度]
04:35:25  Memory Consolidation + Report
04:38:01  Wiki Generation

5-Tier vs 3-Tier 调度对比

第二轮采用 5-Tier 渐进调度(第一轮为 3-Tier),并发度均为 3:

第二轮(5-Tier):

Tier维度维度数候选产出耗时
1architecture, swift-objc-idiom2225m 12s
2coding-standards, design-patterns, networking-api3118m 20s
3error-resilience, concurrency-async, data-event-flow3227m 25s
4ui-interaction, testing-quality, security-auth3247m 30s
5performance-optimization, observability-logging, agent-guidelines3197m 48s
合计149836.3m

第一轮(3-Tier):

Tier维度数候选产出耗时
121020m 49s
22224m 28s
3105021m 57s
合计148232.5m

关键差异:第一轮的 Tier 3 把 10 个维度堆在一起,并发 3 意味着需要 4 波串行执行;第二轮将其拆为 3+3+3,每 Tier 只需 1 波即可完成。Tier 间隔更短,反射(Reflection)也从 3 次增加到 5 次,跨维度知识传递更密集。

最终产出

类别第一轮第二轮变化
候选知识 (Candidates)10198-3%
有效维度12/1413/14+1
QualityGate 满分维度8/1410/14+2
Wiki 文档88
Cursor Rules1213 rules + 6 topics+7
Project Skills55
Agent 指令文件11
语义记忆166220+32.5%
Findings83131+57.8%
Cross-refs2837+32.1%
Reflections35+66.7%

19.3 AgentRuntime 执行实录

维度级指标(第二轮)

每个维度都经历 Analyze → QualityGate → Produce 的 PipelineStrategy 管线:

维度Input TokenTool Calls候选QG 分耗时备注
architecture326,4232811663m 22sevidence=0
swift-objc-idiom913,54356111005m 12s
design-patterns0005m 30s⚠ analyze hard timeout
coding-standards702,4374491007m 37sproduce fast-retry
networking-api477,389342708m 20sdepth=0,第一轮完全退化
data-event-flow779,0014251006m 24s
concurrency-async1,163,3645471007m 17s1 rejected
error-resilience1,040,55754101007m 25s
testing-quality892,9515891006m 33s
security-auth1,030,2415281006m 39s
ui-interaction1,066,8975871007m 30s1 rejected
agent-guidelines613,437295664m 57sevidence=0,第一轮完全退化
performance-opt1,136,1445171007m 39s
observability-logging1,005,1374971007m 48s
合计11,147,5216099836.3m

两轮对比关键发现:

  1. Token 消耗上升 34.9%(11.1M vs 8.3M):自适应预算将 maxIterations 从 24 提高到 34,Agent 在 EXPLORE 阶段有更多轮次深入阅读源码。concurrency-async(1.16M)和 performance-optimization(1.14M)成为 Token 消耗最高的维度,因为它们需要跨 Package 追踪 ThreadSafeDictionaryOSAllocatedUnfairLock 等并发原语的使用链路。

  2. 第一轮两个退化维度恢复networking-api(第一轮: 0 token / 0 产出 → 第二轮: 477K token / 2 候选 / QG=70)和 agent-guidelines(第一轮: 0/0 → 第二轮: 613K / 5 候选 / QG=66)。5-Tier 调度让这两个维度不再与 8 个强维度挤在同一 Tier 中竞争资源。

  3. 新退化维度 design-patterns:analyze 阶段 hard timeout(330s),LLM 调用完全无响应。与第一轮的 architecture produce timeout 类似——这是 Agent 偶发的 “冻结” 现象,abortSignal 在 330s 后强制中断并继续管线。

  4. fast-retry 首次触发coding-standards 的 produce 阶段首次超时(210s,0 tool calls),fast-retry 自动触发 retryBudget → 重试后 14 iters / 11 tool calls → 产出 9 条候选。这是第二轮新增的容错链路首次在测试中触发。

候选产出分布(第二轮)

architecture            ███████████   11
swift-objc-idiom        ███████████   11
error-resilience        ██████████    10
coding-standards        █████████      9  ← fast-retry 救回
testing-quality         █████████      9
security-auth           ████████       8
ui-interaction          ███████        7
concurrency-async       ███████        7
performance-opt         ███████        7
observability-logging   ███████        7
data-event-flow         █████          5
agent-guidelines        █████          5  ← 第一轮完全退化,第二轮恢复
networking-api          ██             2  ← 第一轮完全退化,第二轮恢复
design-patterns         ░░░░           0  ← analyze hard timeout

13 个有效维度的平均产出为 7.5 条候选。Gateway 共拒绝 3 条(concurrency-async 1 条、ui-interaction 1 条、agent-guidelines 1 条),验证通过率 97.0%(第一轮为 95.3%)。

19.4 ExplorationTracker 相位转换

SCAN→EXPLORE:一致的 iter=2 触发

第二轮的所有维度都在 iter=2 时从 SCAN 转入 EXPLORE(第一轮为 iter=3)。这是因为 explorationThreshold 从 3 降低到 2——Agent 只需 1 次结构扫描 + 1 次文件列表读取即可进入深度代码阅读,节省了约 10-15 秒/维度。

从第二轮日志摘录典型转换:

SCAN → EXPLORE (iter=2, dwellMs=9670,  files=3,  patterns=5)   architecture
SCAN → EXPLORE (iter=2, dwellMs=11392, files=5,  patterns=0)   swift-objc-idiom
SCAN → EXPLORE (iter=2, dwellMs=10869, files=0,  patterns=5)   coding-standards
SCAN → EXPLORE (iter=2, dwellMs=16409, files=0,  patterns=0)   design-patterns
SCAN → EXPLORE (iter=2, dwellMs=21974, files=8,  patterns=12)  networking-api
SCAN → EXPLORE (iter=2, dwellMs=20415, files=1,  patterns=4)   error-resilience
SCAN → EXPLORE (iter=2, dwellMs=25900, files=19, patterns=13)  concurrency-async
SCAN → EXPLORE (iter=2, dwellMs=33921, files=11, patterns=8)   data-event-flow
...

Analyze 阶段的标准相位序列(第二轮)

error-resilience 为例(完整 SCAN → EXPLORE → VERIFY → SUMMARIZE):

SCAN ─ 20s ─→ EXPLORE ─ 183s ─→ VERIFY ─ 13s ─→ SUMMARIZE
  iter=2         iter=25          iter=26
  files=1        files=34         files=34

对比 concurrency-async(maxIterations 强制中断):

SCAN ─ 26s ─→ EXPLORE ──── 230s ──→ SUMMARIZE (maxIter=34/34 forced)
  iter=2         files=29→38

驻留时长统计(两轮对比)

阶段第二轮中位数第二轮最小第二轮最大第一轮中位数
SCAN18s10s34s22s
EXPLORE201s86s270s139s
VERIFY15s1s21s30s

第二轮变化

  • SCAN 缩短:iter=2 提前退出,中位从 22s 降到 18s
  • EXPLORE 大幅延长:maxIter=34(vs 24)给予 Agent 更充裕的深度阅读时间,中位从 139s 升到 201s,最高达 270s(performance-optimization)
  • VERIFY 缩短:更多维度在 EXPLORE 阶段已触达 maxIterations 直接跳入 SUMMARIZE,VERIFY 变得更短甚至被跳过

maxIterations 强制退出统计

第二轮中有 7 个维度 的 Analyze 阶段触发了 maxIterations reached (34/34), forcing → SUMMARIZE(第一轮为 6/24):

维度EXPLORE 最终 filespatterns
swift-objc-idiom3838
coding-standards4755
concurrency-async2930
data-event-flow3834
security-auth3755
observability-logging2732
performance-optimization4321

自适应预算从 24 增到 34 轮(+41.7%),但仍有半数维度耗尽预算。对于 124 文件的中型项目,34 轮预算让 Agent 平均触达 35+ 文件和 35+ 模式——而第一轮为 22 文件。

Produce 阶段的饱和退出(第二轮)

Produce 阶段出现了三种结束模式:

  1. 正常饱和退出Exploration saturated at iter 10/24 — files=6, staleRounds=7。Agent 发现没有新文件可读取后自然结束,平均在 iter 9-13 退出。这是最常见的模式。

  2. SUMMARIZE 转换退出PRODUCE → SUMMARIZE (iter=7-13, submits=5-11)。Agent 认为已产出足够候选后主动结束。

  3. Fast-retry 退出coding-standards produce 首次超时(210s,0 tool calls)→ ♻️ fast-retrying with retryBudget → 5 iters / 2 submits 后完成。这是第二轮新增的退出路径。

19.5 上下文窗口压缩

ContextWindow 的三级渐进压缩在第二轮执行中触发了 12 次 L1 级(第一轮为 7 次):

触发时间压缩前 TokenBudget占比截断条目
05:54:4416,61648,00034.6%11
06:02:4416,31348,00034.0%13
06:02:4616,23448,00033.8%12
06:03:0917,44848,00036.4%11
06:09:5120,19748,00042.1%9
06:10:0518,96348,00039.5%10
06:10:1719,94548,00041.6%10
06:11:4524,92848,00051.9%6
06:16:4820,37148,00042.4%10
06:17:0719,07048,00039.7%9
06:17:1719,56848,00040.8%11
06:18:2725,85148,00053.9%6

两轮对比

  • 触发次数增加:12 次 vs 7 次——maxIterations=34 意味着更多轮对话积累,压缩需求更频繁
  • 最高占比更高:53.9% vs 40.3%——部分维度(如 security-auth、performance-optimization)在 34 轮深度分析后窗口压力更大
  • L2/L3 仍未触发——L1 裁剪(截断旧 tool result)在两次执行中均足够维持窗口可控
  • 截断条目范围:6-13 条/次(均值 9.8),与第一轮的 10-12 条/次接近

结论不变:对于 124 文件的中型项目,L1 已是上限。L2(摘要级压缩)和 L3(全量重写)设计更多针对大型 monorepo(1000+ 文件)场景。

19.6 质量门控(QualityGate)

QualityGate 在每个维度的 Analyze 阶段结束后评分,使用四维度模型。以下是第二轮数据(附第一轮对照):

维度第二轮 TotalDepthBreadthEvidenceCoherence第一轮 Total
architecture66100100080100
swift-objc-idiom100100100100100100
design-patterns100
coding-standards100100100100100100
networking-api700100100100(退化)
data-event-flow100100100100100100
concurrency-async100100100100100100
error-resilience10010010010010066
ui-interaction100100100100100100
testing-quality100100100100100100
security-auth100100100100100100
performance-opt100100100100100100
observability-logging100100100100100100
agent-guidelines6610099.0080(退化)

两轮 QualityGate 对比:

  1. 满分率:第二轮 10/14 vs 第一轮 8/14(排除退化维度后)

  2. 退化维度完全不同

    • 第一轮退化(0 token / 0 tool calls):networking-apiagent-guidelines
    • 第二轮退化(hard timeout):design-patterns
    • 第一轮的两个退化维度在第二轮恢复,虽然分数不满(networking-api=70, agent-guidelines=66),但已能正常分析并产出候选
  3. architecture 分数下降(100 → 66):第二轮中 evidence=0,评语 “Findings lack file-level evidence”。analyze 仅 12 iters 即完成(SCAN→EXPLORE→VERIFY→SUMMARIZE 全流程走完),分析深度足够但文件级证据引用缺失。

  4. error-resilience 分数上升(66 → 100):第一轮中该维度 evidence=0 / coherence=80,第二轮得益于更充裕的 34 轮预算,Agent 有足够轮次收集文件级证据。

QualityGate 阈值仍为 50 分(pass),"宽准入、靠产出筛选" 的设计意图不变:architecture(66 分)和 agent-guidelines(66 分)均通过门控,最终分别产出 11 和 5 条候选知识。

19.7 记忆蒸馏与语义记忆

Bootstrap 管线的最终阶段将短期分析结果(Tier 2 SessionStore)蒸馏为长期语义记忆(Tier 3 PersistentMemory),供后续会话和二次冷启动复用。这一过程借鉴了 Generative Agents(Park et al., 2023)的三层记忆架构与 Mem0 的冲突解决策略。

三层记忆架构

┌─────────────────────────────────────────────────────┐
│  Tier 1 · WorkingMemory (ContextWindow)              │
│  ── Agent 单轮上下文,随对话窗口滑动清除 ──           │
└──────────────────────┬──────────────────────────────┘
                       │ 维度完成时 flush
┌──────────────────────▼──────────────────────────────┐
│  Tier 2 · SessionStore (内存)                        │
│  ── 维度报告 + findings + Tier Reflections ──        │
│  生命周期: 一次 Bootstrap 会话                       │
└──────────────────────┬──────────────────────────────┘
                       │ EpisodicConsolidator 蒸馏
┌──────────────────────▼──────────────────────────────┐
│  Tier 3 · PersistentMemory (SQLite)                  │
│  ── semantic_memories 表,跨会话持久化 ──             │
│  类型: fact / insight / preference                   │
│  生命周期: 30 天归档衰减 → 90 天遗忘 → MAX_MEMORIES  │
└─────────────────────────────────────────────────────┘

蒸馏管线:EpisodicConsolidator

管线启动时机:所有 Tier 完成后,orchestrator.ts Step 5 触发。

Pipeline 完成
  → compact() 过期清理
  → #extractFromFindings()       → fact 记忆
  → #extractFromReflections()    → insight + high-priority fact
  → #extractFromAnalysisText()   → 正则提取 fact/insight
  → MemoryConsolidator.consolidate() → 去重/合并/冲突解决
  → enforceCapacity() 容量控制

三个提取器的策略差异:

提取器输入源产出类型重要性策略过滤阈值
#extractFromFindings维度 findings 列表fact继承原始 importanceimportance ≥ 4, 长度 ≥ 10
#extractFromReflectionsTierReflection.crossDimensionPatternsinsight固定 7(跨维度高权重)长度 ≥ 10
TierReflection.suggestionsForNextTierinsight固定 5(建议性质)长度 ≥ 10
TierReflection.topFindings (imp ≥ 7)fact继承原始importance ≥ 7
#extractFromAnalysisText分析文本正则匹配fact / insight固定 4(正则置信度偏低)10 ≤ 长度 ≤ 120, 每维度上限 5+3

BiliDili 实际蒸馏数据

第二轮数据(附第一轮对照):

[Insight-v3] Memory stats: 14 dims, 131 findings, 134 files, 37 cross-refs, 5 reflections
                     (第一轮: 14 dims, 83 findings,  143 files, 28 cross-refs, 3 reflections)

[Consolidator] Extracted 259 candidate memories: 126 findings, 109 insights, 24 text facts
                     (第一轮: 173 candidates:         83 findings,  63 insights, 27 text facts)

[Consolidator] Per-dimension (top 6):
  concurrency-async=29, performance-optimization=26, ui-interaction=23,
  swift-objc-idiom=20, networking-api=17, design-patterns=13
                     (第一轮: design-patterns=18, coding-standards=16,
                      swift-objc-idiom=15, concurrency-async=14)

[Consolidator] Importance distribution: [1-3]=0 [4-6]=69 [7-10]=190 | Entities: 438
                     (第一轮: [1-3]=0 [4-6]=90 [7-10]=83 | Entities: 247)

[MemoryConsolidator] Consolidation: +220 ADD, ~28 UPDATE, ⊕11 MERGE, =0 SKIP  (293ms)
                     (第一轮: +166 ADD, ~2 UPDATE,  ⊕5 MERGE,  =0 SKIP  (221ms))

[Insight-v3] Total: 220 memories (avg importance: 7.0)
                     (第一轮: 166 memories, avg importance: 7.2)

[Insight-v3] Memory by type: fact=161, insight=59 | by source: bootstrap=220
[Insight-v3] Importance histogram: imp4=24 imp5=41 imp6=4 imp7=55 imp8=58 imp9=71 imp10=6
                     (第一轮: imp4=27 imp5=63 imp7=36 imp8=25 imp9=15 imp10=0)

第二轮蒸馏变化分析

记忆量增长 32.5%(166 → 220)的三个来源:

  1. Findings 增长 57.8%(83 → 131):第二轮的 5 次 Tier 反射产生更多跨维度 findings
  2. Cross-refs 增长 32.1%(28 → 37):5-Tier 的密集反射使维度间关联发现增加
  3. 两个退化维度恢复:networking-api(+17 候选记忆)和 agent-guidelines(+? 候选记忆)在第一轮中贡献为零

重要性分布右移:第二轮的 [7-10] 区间记忆从 83 条增加到 190 条(+129%),而 [4-6] 区间从 90 条降到 69 条。这意味着提取器产出了更多高权重记忆——主要因为 reflections 从 3 增加到 5,而 crossDimensionPatterns 的固定 importance=7 大量注入高权重 insight。

实体提取翻倍:438 vs 247(+77.3%)。更多维度完成分析意味着更多类名、文件名被关联到记忆条目中。

蒸馏衰减管线(第二轮)

步骤第二轮第一轮说明
原始候选记忆259173第二轮: 126 findings + 109 insights + 24 text facts
去重合并(MERGE)-11-5Jaccard ≥ 0.60
更新已有(UPDATE)~28~2第二轮库中有第一轮残留记忆,大量触发 UPDATE
跳过(SKIP)00无完全重复项
最终写入220166第二轮 avg importance: 7.0 / 第一轮: 7.2

UPDATE 数大幅上升(28 vs 2)的原因:第二次冷启动时数据库中已有第一轮写入的 166 条记忆,MemoryConsolidator 在 Phase 2 的相似度匹配中将 28 条与已有记忆合并(similarity ≥ 0.85),提升了 importanceaccess_count。这是二次冷启动增量更新的实际表现。

智能固化:MemoryConsolidator 决策树

每条候选记忆经过两阶段处理:

Phase 1 — Mem0 冲突预解决

对已有记忆库做矛盾检测:如果新记忆与旧记忆主题一致但一条包含否定词("不再使用"/"deprecated"),则判定为矛盾,用新记忆替换旧记忆。

// 矛盾检测逻辑
主题重叠 = Jaccard(topicWords_A, topicWords_B) ≥ 0.3 或 overlap ≥ 2 词
否定不一致 = 一方匹配 /不再使用|禁止|deprecated|don't/ 而另一方不匹配
→ 判定矛盾 → REPLACE (用新内容替换旧记忆)

Phase 2 — Similarity-based Consolidation

对每条候选记忆:
  1. findSimilar(content, type, limit=3)
     └─ 使用 Jaccard + 子串包含加成 (0.3 bonus)
  2. 无匹配 (similarity < 0.1) → ADD
  3. similarity ≥ 0.85         → UPDATE (提升 importance + access_count)
  4. similarity ≥ 0.60         → MERGE (拼接 content, 取 max(importance))
  5. 其他                      → ADD

BiliDili 的 259 条候选中(第二轮),由于库中已有第一轮的 166 条记忆,大量触发 UPDATE(28 条)和 MERGE(11 条),而非全量 ADD。这是 二次冷启动 的标志性模式——增量更新而非全量重写。

5 条 MERGE 来自跨维度重叠升级为第二轮的 11 条 MERGE:concurrency-asyncperformance-optimization 都提到 ThreadSafeDictionaryerror-resiliencenetworking-api 都提到 RetryMiddleware——5-Tier 的更密集反射使跨维度重叠发现增加了一倍。

实体提取

每条候选记忆同时提取关联实体(类名、文件名等),存入 related_entities 字段:

  • CamelCase 类名/\b[A-Z][a-zA-Z]*[A-Z][a-zA-Z]*\b/ThreadSafeDictionary, NetworkMiddleware
  • Evidence 文件名:从 finding.evidence 中解析 file.swift:line

BiliDili 第二轮总共提取 438 个实体引用(第一轮: 247,+77.3%),平均每条记忆 2.0 个实体(第一轮: 1.5)。实体密度提升意味着后续检索时关键词匹配更精准。

记忆生命周期

写入 semantic_memories 表后,记忆进入生命周期管理:

阶段触发时机操作
活跃写入后正常检索,access_count 递增
归档衰减30 天未访问 & importance < 3importance -= 1(最低为 1)
遗忘90 天未访问 & importance < 7从数据库删除
过期TTL 到期从数据库删除
容量淘汰总数 > 500按 importance ASC + access_count ASC 删除溢出部分

这意味着重要性 ≥ 7 的记忆永远不会被自动遗忘(只会被容量淘汰),而正则提取的低置信度记忆(importance=4)如果 90 天内未被检索引用,将被自动清理。

检索打分:Generative Agents 三维模型

记忆写入后,二次冷启动或日常对话通过 MemoryRetriever.retrieve() 检索。打分公式:

score=0.2×recency+0.3×importance+0.5×relevance

其中:

  • recency = eΔtln2/T1/2,半衰期 T1/2=7
  • importance = importance / 10(归一化)
  • relevance = 当有向量嵌入时 0.6 × cosine + 0.4 × lexical,否则纯词汇匹配

检索结果注入 §8 历史语义记忆 提示词段,格式:

markdown
## 项目记忆 (10 条最相关)
- ⚠️ [fact] ThreadSafeDictionary 是项目的核心并发基础设施,入度 38...
- 📌 [insight] concurrency-async 与 performance-opt 共享依赖...
- 💡 [fact] 项目使用 os.Logger 的静态分类器进行日志...

Badge 规则:⚠️ importance ≥ 8, 📌 importance ≥ 5, 💡 其他。

Tier 间反射产出

第二轮(5 Tiers):

TierDimensionsTop FindingsCross-patternsSuggestions
Tier 1architecture, swift-objc-idiom101
Tier 2coding-standards, design-patterns, networking-api105
Tier 3error-resilience, concurrency-async, data-event-flow105
Tier 4ui-interaction, testing-quality, security-auth105
Tier 5performance-opt, observability-logging, agent-guidelines105

第一轮(3 Tiers):

TierTop FindingsCross-patternsSuggestions
Tier 11043
Tier 21032
Tier 31054

第二轮的 Cross-patterns 总量从 12 增加到 21(+75%)。每个 cross-pattern 转化为 importance=7 的 insight 记忆,是语义记忆中跨维度洞察的主要来源。5-Tier 比 3-Tier 多出两次反射机会,使 Tier 2-5 的后续维度在分析时能引用更多前序发现。

19.8 交付产物一览

候选知识按维度分布(第二轮)

维度                     候选数   rejected   净产出   第一轮净产出
──────────────────────────────────────────────────────────
architecture               11        0        11         0
swift-objc-idiom           11        0        11        10
error-resilience           10        0        10         4
coding-standards            9        0         9        10
testing-quality             9        0         9        10
security-auth               8        0         8        10
ui-interaction              7        1         6         6
concurrency-async           7        1         6        10
performance-optimization    7        0         7         7
observability-logging       7        0         7         5
data-event-flow             5        0         5        10
agent-guidelines            5        1         4         0
networking-api              2        0         2         0
design-patterns             0        0         0        12
──────────────────────────────────────────────────────────
合计                       98        3        95        82
                                                 + 19 post
                                                 = 101 第一轮

全部交付清单(第二轮)

交付物路径数量第一轮对照
候选知识Alembic/candidates/*/98101
Cursor Rules (A).cursor/rules/alembic-project-rules.mdc13 rules12
Cursor Patterns (B).cursor/rules/alembic-patterns-*.mdc6 topics (23 patterns + 9 facts + 18 insights)
Project Skills (C)Alembic/skills/55
Agent 指令 (F)AGENTS.md + copilot-instructions2,165 tokens1 file
WikiAlembic/wiki/8 articles (8 AI-enhanced)8
语义记忆.asd/memory/220166
Bootstrap 报告.asd/bootstrap-report.json11

Cursor Delivery 通道明细(第二轮新增)

第二轮新增了 Channel B 的多主题 pattern 分发:

Channel A: 13 rules → alembic-project-rules.mdc          (785 tokens)
Channel B: networking  — 5 patterns + 2 facts                 
         : ui         — 5 patterns + 0 facts                 
         : architecture — 5 patterns + 5 facts               
         : data       — 5 patterns + 0 facts                 
         : conventions — 3 patterns + 2 facts                 
         : call-architecture — 18 insights                   (3,983 tokens total)
Channel C: 5 builtin skills synced                            
Channel F: 1 agent instruction file                           (2,165 tokens)
Total delivery: 26ms

真实样本:一个高质量 Candidate 如何变成交付产物

这里先做一个必要说明:本轮还停留在 Candidate 阶段,尚未进入人工审核后的正式 Recipe 阶段,因此 Alembic/recipes/ 目录为空。所以下面展示的不是“已审核 Recipe”,而是最接近最终 Recipe 的高质量 Candidate,以及它进入交付通道后的真实输出形态。

同时也要强调,下面这批结果并不是由当前最强大的 LLM 生成。两轮测试使用的是 gemini-3-flash-preview,目标是观察当前工程链路在较低成本、偏速度优先模型上的真实表现,而不是展示高配模型的上限。

本章改选一个独立且唯一的样本:@metrics-collector。之所以换成它,是因为它不是一组规范的组合,而是围绕同一个类、同一个文件、同一个工程决策展开,边界更清晰。

  1. 它来自 BiliDili 的真实基础设施代码,而不是抽象概念。
  2. 它能同时落到规则、pattern 和 Wiki 三类交付物中。
  3. 它很容易判断是否“像项目自己的知识”,而不是泛化的 Swift 教程。
样本类型来源质量
@metrics-collectorpattern candidatePackages/AOXNetworkKit/Sources/AOXNetworkKit/Monitor/MetricsCollector.swiftconfidence = 0.9

这个样本的核心信息不是“项目有监控模块”这么宽泛,而是抽出了一条非常具体的工程事实:BiliDili 在网络可观测性里,用 MetricsCollector 收集请求指标,并用 OSAllocatedUnfairLock 保护高频更新的共享状态。 这不是通用 Swift 教程会自然写出的内容,而是和 AOXNetworkKit 内部实现强绑定的项目知识。

Candidate 原文里已经能看到这种项目特异性:

markdown
### MetricsCollector 网络指标收集与并发安全

- 使用 `MetricsCollector` 收集请求路径、状态码、耗时及流量大小
- 使用 `OSAllocatedUnfairLock` 保护指标历史记录
- 该实现来自 `Packages/AOXNetworkKit/.../MetricsCollector.swift`

进入 Channel A / Cursor Rules 后,这条知识没有被一字不差地下发,而是被进一步抽象成全项目通用约束:

markdown
- [swift] Use OSAllocatedUnfairLock for protecting simple, frequently accessed mutable state in concurrent contexts.
  Do NOT use heavy locks like NSLock or serial DispatchQueues for simple integer counters or flags.

进入 Channel B / Networking Patterns 后,同一事实又被保留为更贴近网络层的模式卡片:

markdown
### @metrics-collector
- When: When implementing network performance monitoring or telemetry.
- Do: Use MetricsCollector with OSAllocatedUnfairLock to record RequestMetrics and provide aggregated statistics.
- Why: 这是项目在高频网络事件下维持低开销可观测性的具体实现。

如果继续看 Wiki 输出,也能看到同一主题以“模块说明”的形式出现。虽然 Wiki 不会逐条照搬 Candidate,但 modules/aoxnetworkkit.md 已经明确把 MetricsCollector 放进 AOXNetworkKit 的核心组件图和协作流程里,说明这条知识并没有在交付阶段丢失,而是被提升到了模块级说明。

这个单点样本更能说明问题:冷启动的价值不只是“提取出 98 条候选”,而是它可以围绕一个真实类(MetricsCollector)抽出一条独立知识,再分别把它变成 Candidate、Cursor Pattern、Cursor Rule 和 Wiki 说明。即便当前使用的不是最强模型,仍然已经能把这种“项目内部的具体实现”稳定地转译成多通道交付内容。

19.9 数据洞察总结

效率指标(两轮对比)

指标第二轮第一轮变化
每候选 Token 消耗~114K input~83K+37.3%
每候选 Tool Calls~6.2 calls~5+24%
每候选耗时~22.2s~19s+16.8%
Input/Output Token 比62.6:160:1+4.3%
维度成功率13/14 = 92.9%12/14 = 85.7%+7.2pp
QG 满分率10/14 = 71.4%8/14 = 57.1%+14.3pp
Gateway 验证通过率95/98 = 97.0%~94/98 = 95.9%+1.1pp
语义记忆产出220166+32.5%
Findings 产出13183+57.8%

第二轮每条候选的 Token 消耗上升 37.3%,但维度成功率 +7.2pp,语义记忆 +32.5%。这是“用预算换覆盖率”的工程权衡:自适应预算(34 轮)让 Agent 有更多轮次深入分析,减少了退化维度但增加了单候选成本。

退化分析(第二轮仅 1 个退化维度)

第一轮有 3 个退化维度(architecture produce timeout + networking-api / agent-guidelines 完全退化),第二轮仅剩 1 个

design-patterns(analyze hard timeout)

  • Analyze 阶段 330s 超时,0 iters,0 tool calls——LLM 调用完全无响应
  • abortSignal 在超时后立即触发 ⛔ abortSignal fired during LLM call — exiting
  • SessionStore 仍存储了 8 findings / 0 files 的报告(来自 fallback 数据)
  • 该维度在第一轮中正常完成(QG=100, 12 candidates)——这说明 LLM “冻结” 是随机事件而非系统性缺陷

第一轮退化维度在第二轮的表现:

维度第一轮状态第二轮状态第二轮产出
networking-api完全退化(0 token, 0 calls, 330s timeout)QG=70, 34 tool calls, 477K tokens2 候选, 11 findings
agent-guidelines完全退化(0 token, 0 calls, 330s timeout)QG=66, 29 tool calls, 613K tokens5 候选, 0 findings
architecture (produce)QG=100 但 produce timeout(0 calls)QG=66, 28 tool calls, 11 候选正常产出

恢复的可能因素:5-Tier 调度——第一轮中 networking-api 和 agent-guidelines 与 8 个强维度挤在 Tier 3 中(10 维度 / 并发 3 = 3+ 波串行),资源争抢可能导致 LLM API 请求被流控。第二轮将它们分配到 Tier 2(networking-api)和 Tier 5(agent-guidelines),每 Tier 仅 3 维度 / 并发 3 = 1 波即完成。但仅凭两次测试无法确认因果关系,也可能是 LLM API 状态的偶然差异。

容错链路验证

第二轮首次在测试中触发了三条容错路径:

容错机制触发场景结果
hard timeout + abortSignaldesign-patterns analyze 330sLLM 调用被中断,管线继续
fast-retrycoding-standards produce 210s + 0 calls自动重试 → 14 iters → 9 候选
SUMMARIZE grace retry多个维度的 forced summary 返回空响应grace 2/2 重试后兜底总结

fast-retry 的 coding-standards 案例值得注意:如果没有这条路径,该维度将只产出 0 条候选(与第一轮的 architecture produce timeout 相同结局),而实际上重试后产出了 9 条。

从数据看设计决策

  1. 5-Tier 调度 vs 3-Tier:退化维度从 2 减少到 0(不计算 LLM 冻结的 design-patterns),跨维度 cross-patterns 从 12 增加到 21,反射频率增加但总时长仅增加 3.8 分钟。但仅凭两次测试无法确认这是调度策略的贡献还是 LLM 随机性的影响。

  2. 自适应预算computeAnalystBudget(124)=34 让 Agent 在 EXPLORE 阶段平均触达 35+ 文件,error-resilience 的 QG 从 66 分升到 100 分。代价是 7/14 维度仍耗尽预算——34 对于 124 文件的中型项目是合理但仍偏紧的值。

  3. SCAN→EXPLORE 提前 1 轮:iter=2 而非 iter=3 节省了约 10-15 秒/维度(14 维度共 2-3 分钟)。更重要的是减少了 Agent 在 SCAN 阶段的无效规划,尽早进入代码阅读。

  4. 二次冷启动的增量更新模式:28 条 UPDATE 表明 MemoryConsolidator 的相似度合并机制在增量场景下正常工作。二次冷启动不是“推倒重来”,而是“更新增强”。

  5. L1 压缩仍是上限:12 次 L1 已可控,但最高 53.9% 窗口占比接近 60% 阈值。如果项目文件数翻倍到 250+,可能会触发 L2。

19.10 第一轮 → 第二轮 全景对比

核心指标对比表

指标第一轮(优化前)第二轮(优化后)Δ
调度策略3-Tier (2+2+10)5-Tier (2+3+3+3+3)更均衡
Analyze 预算固定 24 轮自适应 34 轮+41.7%
SCAN 阈值iter=3iter=2-1 轮
总时长32.5 min36.3 min+11.7%
Input Tokens8,263,08611,147,521+34.9%
Output Tokens138,119177,863+28.8%
Tool Calls498609+22.3%
候选知识101 (82+19)98-3.0%
有效维度12/1413/14+1
QG 100分8/1410/14+2
退化维度2(完全退化)0(1 LLM 冻结)-2
Findings83131+57.8%
Cross-refs2837+32.1%
Reflections35+66.7%
语义记忆166220+32.5%
实体引用247438+77.3%
L1 压缩次数712+71.4%

成本 vs 收益分析

额外投入:                         额外产出:
  +2.8M input tokens (34.9%)        +1 有效维度 (networking-api 恢复)
  +111 tool calls (22.3%)           +48 findings (57.8%)
  +3.8 min wall time (11.7%)        +54 语义记忆 (32.5%)
                                    +9 cross-refs (32.1%)
                                    +2 reflections (66.7%)
                                    +191 实体引用 (77.3%)
                                    +1 fast-retry 救回的维度

每增加 1M input token,换来约 17 条额外 findings 和 19 条语义记忆。总成本增加 34.9% 但知识密度(findings/token)反而提升了 17%(131/11.1M vs 83/8.3M)——这可能说明自适应预算让 Agent 的阅读更有针对性,但也可能有 LLM 随机性的影响。

下一章将以同一份数据为基础,展示从 Candidate 到 Recipe 的人工审核流程,以及 Guard 引擎如何将 Recipe 转化为实时代码校验规则。

Released under the MIT License.