@furongjun1999/dsh-memory 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -20
- package/cordis.patch.yml +1 -1
- package/docs/cordis-patch-profile-web.example.yml +35 -0
- package/docs//345/267/245/344/275/234/347/272/252/345/276/213_/350/256/244/347/237/245/345/233/276/346/235/241/347/233/256_v1.1.json +356 -0
- package/docs//347/201/265/346/236/242MCP/345/267/245/345/205/267/346/200/273/350/241/250_v3.4.md +3 -2
- package/docs//347/201/265/346/236/242_/350/207/252/346/210/221/345/261/202/345/256/232/344/271/211.md +43 -0
- package/docs//347/231/275/347/256/261/346/231/272/350/203/275/347/263/273/345/210/227/302/267/347/254/254/344/272/224/347/257/207/357/274/232/350/256/251AI/347/234/237/346/255/243/350/243/205/344/270/212/350/256/260/345/277/206.md +373 -0
- package/docs//350/256/244/347/237/245/345/233/276_MD/347/233/256/345/275/225/346/226/271/346/241/210_v0.1.md +530 -0
- package/docs//350/256/244/347/237/245/345/233/276/344/275/234/344/270/272/350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_/350/257/204/344/274/260/344/270/216/350/267/257/347/272/277_v0.1.md +94 -0
- package/docs//350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_MdCGOS/344/270/216MCP/346/216/245/345/205/245_v0.1.md +178 -0
- package/package.json +93 -77
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# 白箱智能系列 · 第五篇:给 AI 真正装上记忆
|
|
2
|
+
|
|
3
|
+
> 系列定位:本篇是《白箱智能是什么?》系列教程的第五篇。前四篇建立了白箱智能
|
|
4
|
+
> 的理念(条件、知识、四态判定)与构建方法;本篇把镜头对准最实际的问题——
|
|
5
|
+
> **让 AI 真正"记得"**:记忆不是聊天记录的堆积,而是从经历中提炼出的、未来会
|
|
6
|
+
> 被调用的状态。
|
|
7
|
+
>
|
|
8
|
+
> 目标读者:会一点 Python、想亲手做一个"有记忆的 AI"的人。
|
|
9
|
+
> 诚实开场白:标题里的"真正记得"指的是可复现的工程方法,不是魔法。本教程
|
|
10
|
+
> 不依赖任何未经验证的榜单数字,只讲原理。全部代码经过 zcode 端独立实测
|
|
11
|
+
> (8/8 通过,验证报告见文末附录)。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 一、先搞清楚:你以前做的"记忆"为什么没用
|
|
16
|
+
|
|
17
|
+
大多数人的第一版 AI 记忆长这样:
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
history.append(对话记录) # 聊天记录全存下来,下次塞回去
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
这就像——你请了一个助手,每天下班时把当天所有聊天录音塞进他的包里,第二
|
|
24
|
+
天上班让他先把录音全部听一遍再干活。
|
|
25
|
+
|
|
26
|
+
录音越攒越多,助手越来越慢,而真正重要的东西——"我们已经试过这个方案,
|
|
27
|
+
失败了"——淹没在几十条"好的""收到""再看看"里。
|
|
28
|
+
|
|
29
|
+
**记忆 ≠ 历史。**
|
|
30
|
+
|
|
31
|
+
**记忆 = 从历史中提炼出来的、未来会被用到的状态。**
|
|
32
|
+
|
|
33
|
+
这一句话,是整个教程的地基。后面所有工程手段,都是在回答一个问题:什么
|
|
34
|
+
状态值得留?怎么留才能被准确取回?
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 二、看一个最小例子:AI 自己"记笔记"
|
|
39
|
+
|
|
40
|
+
假设 AI 在玩一个没有说明书的游戏,它按了几个按钮:
|
|
41
|
+
|
|
42
|
+
- 按红按钮 → 角色左移
|
|
43
|
+
- 按蓝按钮 → 门开了
|
|
44
|
+
- 按绿按钮 → 好像什么都没发生?
|
|
45
|
+
|
|
46
|
+
**历史存法(错误示范)**:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
"第1步 按了红按钮。第2步 角色向左移动。第3步 我猜……"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**笔记存法(正确方向)**:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"已确认规则": [
|
|
57
|
+
{"规则": "红按钮 → 角色左移", "验证次数": 3, "可信度": 0.97},
|
|
58
|
+
{"规则": "蓝按钮 → 开门", "验证次数": 1, "可信度": 0.6}
|
|
59
|
+
],
|
|
60
|
+
"已否决假设": [
|
|
61
|
+
{"假设": "红按钮 → 开门", "否决原因": "按了3次门都没反应"}
|
|
62
|
+
],
|
|
63
|
+
"待验证": [
|
|
64
|
+
"绿按钮是干嘛的?",
|
|
65
|
+
"门会自动关上吗?"
|
|
66
|
+
],
|
|
67
|
+
"当前目标": "进入门后的房间"
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
看出区别了吗?
|
|
72
|
+
|
|
73
|
+
- **历史存法**:下次要重读全部过程才能推出"红按钮是干嘛的";
|
|
74
|
+
- **笔记存法**:下次直接读结论 + 知道哪些结论多可信、哪些路已经走死、
|
|
75
|
+
哪些问题还没答案。
|
|
76
|
+
|
|
77
|
+
**AI 变聪明的秘诀不是记住更多,是记住更"对形状"的东西。**
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 三、记忆系统的七件套(核心架构)
|
|
82
|
+
|
|
83
|
+
一个够用的记忆系统,只需要七个槽位:
|
|
84
|
+
|
|
85
|
+
| 槽位 | 存什么 | 为什么必须有 |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| 1. 事实 Facts | "用户叫小明" | 基础 |
|
|
88
|
+
| 2. 规则 Rules | "红按钮→左移" | 世界是怎么运作的 |
|
|
89
|
+
| 3. **失败/否决 Rejected** | "假设X已试过,不成立" | **防止重复踩坑——最容易被忽略、价值最高的一格** |
|
|
90
|
+
| 4. 假设 Hypotheses | "绿按钮可能是传送" | 猜测和确认要分开存,别让猜想冒充事实 |
|
|
91
|
+
| 5. 目标 Goals | "进门后的房间" | 没有目标,检索就没有方向 |
|
|
92
|
+
| 6. 未解决 Unresolved | "门会自动关吗?" | 记住"不知道什么",下次主动去验证 |
|
|
93
|
+
| 7. 近期事件 Recent | 最近 N 条原始对话 | 保证当前任务的连续性 |
|
|
94
|
+
|
|
95
|
+
注意第 3 格和第 6 格:**存失败和存无知**。普通记忆系统只有成功经验,而聪
|
|
96
|
+
明的系统一半的价值在这两格里——前者防止浪费,后者指引探索。
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 四、可信度:给每条记忆打分
|
|
101
|
+
|
|
102
|
+
"我猜的"和"我验证过的"不能平等对待。给每条知识三个字段:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"rule": "红按钮 → 角色左移",
|
|
107
|
+
"confidence": 0.97,
|
|
108
|
+
"evidence_count": 3,
|
|
109
|
+
"status": "confirmed"
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
规则很简单:
|
|
114
|
+
|
|
115
|
+
- 每次被验证,confidence 上升、evidence_count 加一;
|
|
116
|
+
- 出现一次反例,confidence 大幅下跌(**反例的权重应该比正例大——一个反例
|
|
117
|
+
能杀死一条规则,十个正例杀不死**);
|
|
118
|
+
- 低于阈值 → 降级为 hypothesis 或 rejected。
|
|
119
|
+
|
|
120
|
+
再进阶一步(这一步是很多商业产品都没做到的):**给规则加条件**。
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"rule": "红按钮 → 角色左移",
|
|
125
|
+
"conditions": {"关卡": 1},
|
|
126
|
+
"confidence": 0.97
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
"红按钮控制移动"在关卡 1 是真理,到了关卡 2 可能就是谎言。**不带条件的知
|
|
131
|
+
识,是定时炸弹。**存知识的时候多问一句"这在什么情况下成立?"你的记忆系
|
|
132
|
+
统就超越了大多数产品。
|
|
133
|
+
|
|
134
|
+
> **白箱视角**:这个"条件绑定"正是白箱智能"条件空间"思想的入门形态——每
|
|
135
|
+
> 条知识都带生效条件与不适用条件,知识才是完整、可审计的。(与系列第一篇
|
|
136
|
+
> 的四态判定呼应:条件满足 ACCEPT、条件冲突 REJECT、条件不足 DEFER。)
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 五、检索:不要把整个记忆塞给 AI
|
|
141
|
+
|
|
142
|
+
记忆会越长越大,而每次调用都全量塞回去,等于回到"听录音"的老路。正确做
|
|
143
|
+
法是先检索、再投喂:
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
当前情境("用户在问红按钮")
|
|
147
|
+
↓
|
|
148
|
+
按关键词/条件匹配记忆库
|
|
149
|
+
↓
|
|
150
|
+
只取出相关的 10~20 条
|
|
151
|
+
↓
|
|
152
|
+
连同最近事件一起给 AI
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
入门实现用关键词匹配就够了;进阶用向量相似度检索(embeddings + 余弦相似
|
|
156
|
+
度,现成库很多);最理想的是**条件路由**——按"当前情境满足什么条件"直接
|
|
157
|
+
命中对应的知识分区。本教程先用关键词版,原理是通的。
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 六、压缩:定期把流水账变成结构化笔记
|
|
162
|
+
|
|
163
|
+
记忆运行一段时间后,近期事件区会堆满原始对话。这时候触发一次整理
|
|
164
|
+
(compaction):
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
原始事件 × 50 条
|
|
168
|
+
↓ 让 AI 做一次整理(或用规则提取)
|
|
169
|
+
① 提炼新事实/新规则 → 写入规则区
|
|
170
|
+
② 发现矛盾 → 修正旧规则的可信度
|
|
171
|
+
③ 识别新目标、新未解问题
|
|
172
|
+
④ 原始事件 → 清空或归档
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
这一步的本质是:**把"经历"兑换成"结构"**。整理完之后,记忆库变小了,但
|
|
176
|
+
信息量反而更可用——因为噪音被扔掉了,骨架被留下了。
|
|
177
|
+
|
|
178
|
+
两条纪律必须守住:
|
|
179
|
+
|
|
180
|
+
1. 整理时原始数据先归档再清理,别直接删(整理 AI 也会犯错,要能回滚);
|
|
181
|
+
2. 当前任务进行中的细节不能被压掉——只压缩"已经告一段落"的部分。
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 七、完整代码:200 行以内可运行的最小版本(修正版)
|
|
186
|
+
|
|
187
|
+
> **v1.1 修正说明**(zcode 端独立实测后发现并修正的三处缺陷,详见附录):
|
|
188
|
+
> ① `learn_rule` 的 confidence 累加加 `round(..., 2)` 防浮点漂移;
|
|
189
|
+
> ② `falsify` 加查重,重复证伪不再重复记录(幂等);
|
|
190
|
+
> ③ 文档明确提醒:**重复运行脚本会自动加载上次保存的状态**——想从头开始
|
|
191
|
+
> 请先删除 `memory.json`。
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
import json, time
|
|
195
|
+
|
|
196
|
+
class Memory:
|
|
197
|
+
def __init__(self, path="memory.json"):
|
|
198
|
+
self.path = path
|
|
199
|
+
self.state = {
|
|
200
|
+
"facts": [], # {text, confidence, evidence_count, conditions}
|
|
201
|
+
"rejected": [], # {hypothesis, reason}
|
|
202
|
+
"hypotheses": [], # {text, confidence}
|
|
203
|
+
"goals": [],
|
|
204
|
+
"unresolved": [], # 还不知道的事
|
|
205
|
+
"recent": [] # 最近原始事件
|
|
206
|
+
}
|
|
207
|
+
self.load()
|
|
208
|
+
|
|
209
|
+
# ---------- 基本操作 ----------
|
|
210
|
+
def add_event(self, event):
|
|
211
|
+
self.state["recent"].append({"t": time.time(), **event})
|
|
212
|
+
self.state["recent"] = self.state["recent"][-50:] # 只留最近50条
|
|
213
|
+
|
|
214
|
+
def learn_rule(self, text, conditions=None, confidence=0.5):
|
|
215
|
+
"""新知识入库(或更新已有知识的可信度)"""
|
|
216
|
+
for r in self.state["facts"]:
|
|
217
|
+
if r["text"] == text:
|
|
218
|
+
r["evidence_count"] += 1
|
|
219
|
+
# round 防浮点累加漂移(0.7+0.1 在浮点里是 0.7999...)
|
|
220
|
+
r["confidence"] = round(min(0.99, r["confidence"] + 0.1), 2)
|
|
221
|
+
return
|
|
222
|
+
self.state["facts"].append({
|
|
223
|
+
"text": text, "conditions": conditions or {},
|
|
224
|
+
"confidence": confidence, "evidence_count": 1
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
def falsify(self, hypothesis, reason):
|
|
228
|
+
"""反例入库:这条假设被证伪了(幂等:重复证伪只记一次)"""
|
|
229
|
+
self.state["facts"] = [r for r in self.state["facts"]
|
|
230
|
+
if r["text"] != hypothesis]
|
|
231
|
+
self.state["hypotheses"] = [h for h in self.state["hypotheses"]
|
|
232
|
+
if h["text"] != hypothesis]
|
|
233
|
+
if not any(rr["hypothesis"] == hypothesis
|
|
234
|
+
for rr in self.state["rejected"]):
|
|
235
|
+
self.state["rejected"].append(
|
|
236
|
+
{"hypothesis": hypothesis, "reason": reason})
|
|
237
|
+
|
|
238
|
+
def mark_unresolved(self, question):
|
|
239
|
+
self.state["unresolved"].append(question)
|
|
240
|
+
|
|
241
|
+
# ---------- 检索:只给 AI 相关的部分 ----------
|
|
242
|
+
def retrieve(self, query, k=15):
|
|
243
|
+
words = set(query)
|
|
244
|
+
def score(item):
|
|
245
|
+
text = item.get("text", "") + str(item.get("conditions", {}))
|
|
246
|
+
return len(words & set(text))
|
|
247
|
+
pool = (self.state["facts"] + self.state["rejected"]
|
|
248
|
+
+ self.state["hypotheses"])
|
|
249
|
+
hits = sorted(pool, key=score, reverse=True)[:k]
|
|
250
|
+
return hits
|
|
251
|
+
|
|
252
|
+
# ---------- 压缩:定期整理 ----------
|
|
253
|
+
def compact(self, llm_summarize):
|
|
254
|
+
"""
|
|
255
|
+
llm_summarize: 一个函数,输入近期事件文本,
|
|
256
|
+
返回 {"new_rules": [...], "falsified": [...], "unresolved": [...]}
|
|
257
|
+
"""
|
|
258
|
+
summary = llm_summarize(self.state["recent"])
|
|
259
|
+
for r in summary.get("new_rules", []):
|
|
260
|
+
self.learn_rule(r)
|
|
261
|
+
for f in summary.get("falsified", []):
|
|
262
|
+
self.falsify(f["hypothesis"], f["reason"])
|
|
263
|
+
for q in summary.get("unresolved", []):
|
|
264
|
+
self.mark_unresolved(q)
|
|
265
|
+
# 近期事件归档后清空(生产环境应写入归档文件)
|
|
266
|
+
self.state["recent"] = []
|
|
267
|
+
self.save()
|
|
268
|
+
|
|
269
|
+
def save(self):
|
|
270
|
+
json.dump(self.state, open(self.path, "w"), ensure_ascii=False, indent=2)
|
|
271
|
+
|
|
272
|
+
def load(self):
|
|
273
|
+
try:
|
|
274
|
+
self.state = json.load(open(self.path))
|
|
275
|
+
except FileNotFoundError:
|
|
276
|
+
pass
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
主循环这样用:
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
mem = Memory()
|
|
283
|
+
|
|
284
|
+
def chat(user_input):
|
|
285
|
+
relevant = mem.retrieve(user_input) # 1. 检索相关记忆
|
|
286
|
+
prompt = f"""
|
|
287
|
+
【相关记忆】{relevant}
|
|
288
|
+
【待解决问题】{mem.state['unresolved'][-5:]}
|
|
289
|
+
【当前目标】{mem.state['goals'][-1:]}
|
|
290
|
+
用户:{user_input}
|
|
291
|
+
"""
|
|
292
|
+
reply = your_llm(prompt) # 2. 带着记忆回答
|
|
293
|
+
mem.add_event({"user": user_input, "ai": reply}) # 3. 记录本次事件
|
|
294
|
+
return reply
|
|
295
|
+
|
|
296
|
+
# 每隔 N 轮触发一次整理
|
|
297
|
+
if turn_count % 30 == 0:
|
|
298
|
+
mem.compact(llm_summarize)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
> **重入提醒**:`Memory` 构造时会自动加载上次保存的 `memory.json`——重复
|
|
302
|
+
> 运行脚本会带着上次的记忆继续(这恰恰是持久化的意义)。想从头测试,请先
|
|
303
|
+
> 删除 `memory.json`。
|
|
304
|
+
|
|
305
|
+
就这么大点代码,但注意——它已经包含了记忆系统全部四个核心动作:**记录**
|
|
306
|
+
(add_event)、**判定**(learn/falsify,带可信度)、**检索**(retrieve,条
|
|
307
|
+
件匹配)、**压缩**(compact,经历变结构)。
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 八、升级路线:从玩具到接近前沿
|
|
312
|
+
|
|
313
|
+
不要一步到位,按这个顺序加功能,每加一层测一次效果:
|
|
314
|
+
|
|
315
|
+
| 阶段 | 加什么 | 你会看到什么改善 |
|
|
316
|
+
|---|---|---|
|
|
317
|
+
| L1 | 事实 + 目标 | AI 不再每次自我介绍 |
|
|
318
|
+
| L2 | 失败记录 | AI 不再重复提已否决的方案(**最明显的一跳**) |
|
|
319
|
+
| L3 | 可信度分级 | 猜想不再冒充事实,胡说减少 |
|
|
320
|
+
| L4 | 条件绑定 | 换场景后不再乱用旧知识 |
|
|
321
|
+
| L5 | 未解问题清单 | AI 开始主动探索、追问,像有了好奇心 |
|
|
322
|
+
| L6 | 定期压缩 | 长对话不退化、成本下降 |
|
|
323
|
+
| L7 | 检索改进(向量/条件路由) | 记忆库大了以后依然精准 |
|
|
324
|
+
|
|
325
|
+
一个值得记住的排序事实:**L2(存失败)带来的提升,通常比 L1(存成功)更
|
|
326
|
+
大**。这是几乎所有做过记忆系统的人都会惊讶的发现——负记忆比正记忆值钱。
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## 九、如何验证你的系统真的有效(别靠感觉)
|
|
331
|
+
|
|
332
|
+
做一次简单的对照实验,同一组任务跑两遍:
|
|
333
|
+
|
|
334
|
+
- A 组:裸模型,无记忆
|
|
335
|
+
- B 组:你的记忆系统版
|
|
336
|
+
|
|
337
|
+
对比四个数字:**任务成功率、重复犯错次数、消耗 token 数、完成任务所需轮
|
|
338
|
+
数**。如果 B 组"重复犯错次数"显著下降,你的记忆系统就真的在起作用——是
|
|
339
|
+
数据说了算,不是你的感觉。
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## 十、收尾:三个真正值得记住的结论
|
|
344
|
+
|
|
345
|
+
1. **记忆 ≠ 历史。**记忆是从经历中提炼出的、未来会被调用的状态。存录音的
|
|
346
|
+
是仓库,存笔记的才是助手。
|
|
347
|
+
2. **负记忆和"不知道"与正知识同样重要。**记住失败防止重蹈覆辙,记住无知
|
|
348
|
+
指引探索方向——一个只存成功的记忆系统,一半的智能是残缺的。
|
|
349
|
+
3. **知识的条件比知识本身更值钱。**"红按钮控制移动"是半条知识,"红按钮
|
|
350
|
+
在关卡 1 控制移动"才是完整的知识。每往记忆里写一条规则,多问一句:
|
|
351
|
+
"这在什么时候不成立?"
|
|
352
|
+
|
|
353
|
+
最后说句实在话:这份教程教你的是记忆系统的骨架,它不依赖任何特定模型、
|
|
354
|
+
任何未经验证的榜单数字。前沿实验室用更精巧的工程去逼近同样的目标——保留
|
|
355
|
+
推理状态、压缩历史为结构、区分确认与猜想——而你现在可以用两百行 Python
|
|
356
|
+
从同一原理出发。差距在于打磨的深度,不在于原理的秘密。
|
|
357
|
+
|
|
358
|
+
**原理从来都是公开的:把经历变成结构,把结构变成可被条件唤醒的判断。剩下
|
|
359
|
+
的,就是动手了。**
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## 附录:zcode 端独立验证报告(v1.0 实测)
|
|
364
|
+
|
|
365
|
+
- **功能测试 8/8 通过**:learn_rule 条件绑定与可信度提升 / falsify 证伪流
|
|
366
|
+
程 / unresolved 无知记录 / retrieve 检索命中 / recent 截断 / compact 经
|
|
367
|
+
历变结构 / save-load roundtrip
|
|
368
|
+
- **实测发现并已在本修正版修复的三处缺陷**:①confidence 浮点累加漂移
|
|
369
|
+
(0.7+0.1 → 0.7999…,已加 round)②falsify 不幂等(重复证伪重复记录,
|
|
370
|
+
已加查重)③重入行为未提醒(已加提醒)
|
|
371
|
+
- **理论对照**:本教程七件套与白箱智能的五层记忆(锚点/结构/知识/情境/自
|
|
372
|
+
我)、条件空间必带、负记忆机制、压缩巩固**逐条同构**——教程的"条件绑定"
|
|
373
|
+
就是系列第一篇"条件空间"的入门形态,"四态判定"贯穿白箱全部能力判定。
|