liquid-loop 0.6.4__tar.gz → 0.7.1__tar.gz
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.
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/PKG-INFO +58 -8
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/README.md +57 -7
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop/__init__.py +3 -3
- liquid_loop-0.7.1/liquid_loop/mesh/__init__.py +50 -0
- liquid_loop-0.7.1/liquid_loop/mesh/v2.py +173 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop/storage.py +27 -1
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop/workspace.py +67 -13
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop.egg-info/PKG-INFO +58 -8
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop.egg-info/SOURCES.txt +4 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/pyproject.toml +1 -1
- liquid_loop-0.7.1/tests/test_consensus_expansion.py +45 -0
- liquid_loop-0.7.1/tests/test_nucleate_dual_track.py +115 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/LICENSE +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop/__main__.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop/cli.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop/cognitive_budget.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop/entropy.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop.egg-info/dependency_links.txt +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop.egg-info/entry_points.txt +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop.egg-info/requires.txt +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/liquid_loop.egg-info/top_level.txt +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/setup.cfg +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/tests/test_entropy.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/tests/test_peek_seal.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/tests/test_seal_persistence.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/tests/test_self_evolve.py +0 -0
- {liquid_loop-0.6.4 → liquid_loop-0.7.1}/tests/test_workspace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: liquid-loop
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Self-Organizing Cognitive Memory for AI Agents — Liquid Loop theory implementation
|
|
5
5
|
Author: fishbook0001
|
|
6
6
|
Maintainer: fishbook0001
|
|
@@ -72,7 +72,7 @@ Dynamic: license-file
|
|
|
72
72
|
| **Anchor** 锚点 | 晶种 | 认知关注点,有稳定性值 s ∈ [0,1] |
|
|
73
73
|
| **Evidence** 证据 | 附着粒子 | 锚点下的具体观察,权重指数衰减 w×0.95ᵗ |
|
|
74
74
|
| **Memory** 结晶 | 结晶体 | 2+ 条一致 Evidence 自动凝聚,有置信度 c |
|
|
75
|
-
| **Entropy** 熵值 | 流体无序度 | 八维加权(锚点漂移 / 冲突密度 / 碎片 / 活跃间隔 / 价值衰减 / 锚定强度 / CPE 三维) |
|
|
75
|
+
| **Entropy** 熵值 (LEI) | 流体无序度 | 八维加权(锚点漂移 / 冲突密度 / 碎片 / 活跃间隔 / 价值衰减 / 锚定强度 / CPE 三维) |
|
|
76
76
|
|
|
77
77
|
**状态判定:**
|
|
78
78
|
```
|
|
@@ -81,6 +81,12 @@ YELLOW (0.3 ≤ entropy < 0.6) — 需关注
|
|
|
81
81
|
RED (entropy ≥ 0.6) — 需清理
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
> **关于 "Entropy" 的语义澄清 — Liquid Entropy Index (LEI)**
|
|
85
|
+
>
|
|
86
|
+
> 本项目中的 `entropy` 是 **Liquid Entropy Index (LEI): a system-stability deviation metric, inspired by entropy but NOT equivalent to thermodynamic entropy.**
|
|
87
|
+
> 它不是物理熵 `S = -k Σ pᵢ log pᵢ`,而是对**系统状态偏离稳定流形程度**的综合度量——由八个可解释分量人工加权而成(锚点漂移 / 冲突密度 / 证据碎片 / 活跃间隔 / 价值衰减 / 锚定强度 + CPE 三维:回顾性衰退 / 策略漂移 / 泛化崩塌)。
|
|
88
|
+
> 代码层函数名保留 `calculate()`(历史连续性);文档 / 论文层一律以 **LEI** 指称,避免与热力学熵混淆。
|
|
89
|
+
|
|
84
90
|
---
|
|
85
91
|
|
|
86
92
|
## 快速开始
|
|
@@ -93,7 +99,7 @@ pip install liquid-loop
|
|
|
93
99
|
|
|
94
100
|
### 3 分钟上手
|
|
95
101
|
```python
|
|
96
|
-
from liquid_loop import WorkspaceState, load, save,
|
|
102
|
+
from liquid_loop import WorkspaceState, load, save, calculate
|
|
97
103
|
|
|
98
104
|
# 1. 创建/加载工作区
|
|
99
105
|
state = WorkspaceState() # 或 load(Path("."))
|
|
@@ -111,7 +117,7 @@ for m in state.memories:
|
|
|
111
117
|
print(f"结晶: {m.content[:50]}... (置信度={m.confidence:.2f})")
|
|
112
118
|
|
|
113
119
|
# 5. 监控认知健康
|
|
114
|
-
entropy =
|
|
120
|
+
entropy = calculate(state)
|
|
115
121
|
print(f"熵值: {entropy:.4f} → {'🟢GREEN' if entropy < 0.3 else '🟡YELLOW' if entropy < 0.6 else '🔴RED'}")
|
|
116
122
|
|
|
117
123
|
# 6. 持久化
|
|
@@ -147,6 +153,46 @@ liquid-loop snapshot
|
|
|
147
153
|
|
|
148
154
|
---
|
|
149
155
|
|
|
156
|
+
## MESH 集成(多智能体共识)
|
|
157
|
+
|
|
158
|
+
液环从 v0.7.0 起内置官方 MESH 集成 `liquid_loop.mesh`,把"多智能体共识协议"落地为可复用代码,作为 agent-mesh 节点的标准接入层。
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from liquid_loop.mesh import validate_evidence, compute_cci, cognitive_health, fetch_state
|
|
162
|
+
|
|
163
|
+
# agent 写入前契约自检(零向量:content 必须精确字符串,禁 embedding)
|
|
164
|
+
ok, errs = validate_evidence({"agent_id": "vera", "content": "用户偏好简洁输出"})
|
|
165
|
+
|
|
166
|
+
# 从 8790 拉取记忆状态,算主体间性共识指数 CCI
|
|
167
|
+
items = fetch_state("http://127.0.0.1:8790")
|
|
168
|
+
health = cognitive_health(items)
|
|
169
|
+
print(health["CCI"], health["consensus_crystals"])
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
零向量哲学:一致性判定走**结构化精确相等 + 审计链哈希**,绝不引入任何 embedding / 相似度。规范详见 `mesh/liquid_loop_mesh_v2_spec.md`。
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 定位:Self-Regulating Persistent Memory Dynamics
|
|
177
|
+
|
|
178
|
+
液环的本质不是"AI 意识",而是一套 **agent 系统的自调节持久记忆动力学(Self-Regulating Persistent Memory Dynamics for Agent Systems)**。`AuditChain + LEI(Entropy) + Memory decay` 三者组合形成闭环,使记忆从"外部管理"转向"内部自组织":
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
Input Evidence
|
|
182
|
+
↓
|
|
183
|
+
Memory State ←──────────────┐
|
|
184
|
+
↓ │
|
|
185
|
+
LEI Evaluation (八维熵) │
|
|
186
|
+
↓ │
|
|
187
|
+
Decay / Reinforcement ────────┘
|
|
188
|
+
↓
|
|
189
|
+
AuditChain (SHA256 链式追溯)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
这比单独的 memory store 更接近一个可被实验检验的**动态系统**:输入驱动状态、熵评估稳定性、衰减/强化回流状态、审计链保证来源可信。
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
150
196
|
## 架构对比
|
|
151
197
|
|
|
152
198
|
```
|
|
@@ -193,7 +239,8 @@ liquid-loop/
|
|
|
193
239
|
│ ├── __init__.py # 公共 API 导出
|
|
194
240
|
│ ├── workspace.py # 核心数据模型 + AuditChain + auto_classify + decay
|
|
195
241
|
│ ├── storage.py # JSON 持久化 + 审计链写入
|
|
196
|
-
│ ├── entropy.py #
|
|
242
|
+
│ ├── entropy.py # 八维熵值计算(含 CPE 三维)
|
|
243
|
+
│ ├── mesh/ # MESH v2 多智能体共识协议集成(validate_evidence / compute_cci / ...)
|
|
197
244
|
│ └── cli.py # Click CLI (11 命令)
|
|
198
245
|
├── examples/
|
|
199
246
|
│ └── quickstart.py
|
|
@@ -219,12 +266,15 @@ pytest -v
|
|
|
219
266
|
|
|
220
267
|
## 路线图
|
|
221
268
|
|
|
222
|
-
- [
|
|
223
|
-
- [ ]
|
|
224
|
-
- [ ]
|
|
269
|
+
- [x] 多 Agent 液环耦合(`liquid_loop.mesh` v2 共识协议,2026-07-15 落地)
|
|
270
|
+
- [ ] **[v0.8] 反证轨(Evidence Graph)**:Evidence 分 support / contradiction,一致增稳、冲突降稳,驱动 memory stability score(不再"一致即真")
|
|
271
|
+
- [ ] **[v0.8] 显式时间动力学**:`M(t+1) = M(t) + reinforcement − decay − contradiction_penalty`,让记忆成为"过程"而非"对象"(真正的液态循环)
|
|
272
|
+
- [ ] **[v0.8] 三实验**:E2 错误记忆恢复(核心)→ E3 多 agent 冲突(mesh 价值)→ E1 长期漂移(压力测试)
|
|
225
273
|
- [ ] LoCoMo / LongMemEval 基准对比
|
|
226
274
|
- [ ] 边缘端部署优化(<50KB)
|
|
227
275
|
|
|
276
|
+
> 零向量是液环的硬约束:一致性判定永不引入 embedding / 相似度(这正是液环要替代的方案)。
|
|
277
|
+
|
|
228
278
|
---
|
|
229
279
|
|
|
230
280
|
## 许可证
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
| **Anchor** 锚点 | 晶种 | 认知关注点,有稳定性值 s ∈ [0,1] |
|
|
34
34
|
| **Evidence** 证据 | 附着粒子 | 锚点下的具体观察,权重指数衰减 w×0.95ᵗ |
|
|
35
35
|
| **Memory** 结晶 | 结晶体 | 2+ 条一致 Evidence 自动凝聚,有置信度 c |
|
|
36
|
-
| **Entropy** 熵值 | 流体无序度 | 八维加权(锚点漂移 / 冲突密度 / 碎片 / 活跃间隔 / 价值衰减 / 锚定强度 / CPE 三维) |
|
|
36
|
+
| **Entropy** 熵值 (LEI) | 流体无序度 | 八维加权(锚点漂移 / 冲突密度 / 碎片 / 活跃间隔 / 价值衰减 / 锚定强度 / CPE 三维) |
|
|
37
37
|
|
|
38
38
|
**状态判定:**
|
|
39
39
|
```
|
|
@@ -42,6 +42,12 @@ YELLOW (0.3 ≤ entropy < 0.6) — 需关注
|
|
|
42
42
|
RED (entropy ≥ 0.6) — 需清理
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
> **关于 "Entropy" 的语义澄清 — Liquid Entropy Index (LEI)**
|
|
46
|
+
>
|
|
47
|
+
> 本项目中的 `entropy` 是 **Liquid Entropy Index (LEI): a system-stability deviation metric, inspired by entropy but NOT equivalent to thermodynamic entropy.**
|
|
48
|
+
> 它不是物理熵 `S = -k Σ pᵢ log pᵢ`,而是对**系统状态偏离稳定流形程度**的综合度量——由八个可解释分量人工加权而成(锚点漂移 / 冲突密度 / 证据碎片 / 活跃间隔 / 价值衰减 / 锚定强度 + CPE 三维:回顾性衰退 / 策略漂移 / 泛化崩塌)。
|
|
49
|
+
> 代码层函数名保留 `calculate()`(历史连续性);文档 / 论文层一律以 **LEI** 指称,避免与热力学熵混淆。
|
|
50
|
+
|
|
45
51
|
---
|
|
46
52
|
|
|
47
53
|
## 快速开始
|
|
@@ -54,7 +60,7 @@ pip install liquid-loop
|
|
|
54
60
|
|
|
55
61
|
### 3 分钟上手
|
|
56
62
|
```python
|
|
57
|
-
from liquid_loop import WorkspaceState, load, save,
|
|
63
|
+
from liquid_loop import WorkspaceState, load, save, calculate
|
|
58
64
|
|
|
59
65
|
# 1. 创建/加载工作区
|
|
60
66
|
state = WorkspaceState() # 或 load(Path("."))
|
|
@@ -72,7 +78,7 @@ for m in state.memories:
|
|
|
72
78
|
print(f"结晶: {m.content[:50]}... (置信度={m.confidence:.2f})")
|
|
73
79
|
|
|
74
80
|
# 5. 监控认知健康
|
|
75
|
-
entropy =
|
|
81
|
+
entropy = calculate(state)
|
|
76
82
|
print(f"熵值: {entropy:.4f} → {'🟢GREEN' if entropy < 0.3 else '🟡YELLOW' if entropy < 0.6 else '🔴RED'}")
|
|
77
83
|
|
|
78
84
|
# 6. 持久化
|
|
@@ -108,6 +114,46 @@ liquid-loop snapshot
|
|
|
108
114
|
|
|
109
115
|
---
|
|
110
116
|
|
|
117
|
+
## MESH 集成(多智能体共识)
|
|
118
|
+
|
|
119
|
+
液环从 v0.7.0 起内置官方 MESH 集成 `liquid_loop.mesh`,把"多智能体共识协议"落地为可复用代码,作为 agent-mesh 节点的标准接入层。
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from liquid_loop.mesh import validate_evidence, compute_cci, cognitive_health, fetch_state
|
|
123
|
+
|
|
124
|
+
# agent 写入前契约自检(零向量:content 必须精确字符串,禁 embedding)
|
|
125
|
+
ok, errs = validate_evidence({"agent_id": "vera", "content": "用户偏好简洁输出"})
|
|
126
|
+
|
|
127
|
+
# 从 8790 拉取记忆状态,算主体间性共识指数 CCI
|
|
128
|
+
items = fetch_state("http://127.0.0.1:8790")
|
|
129
|
+
health = cognitive_health(items)
|
|
130
|
+
print(health["CCI"], health["consensus_crystals"])
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
零向量哲学:一致性判定走**结构化精确相等 + 审计链哈希**,绝不引入任何 embedding / 相似度。规范详见 `mesh/liquid_loop_mesh_v2_spec.md`。
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 定位:Self-Regulating Persistent Memory Dynamics
|
|
138
|
+
|
|
139
|
+
液环的本质不是"AI 意识",而是一套 **agent 系统的自调节持久记忆动力学(Self-Regulating Persistent Memory Dynamics for Agent Systems)**。`AuditChain + LEI(Entropy) + Memory decay` 三者组合形成闭环,使记忆从"外部管理"转向"内部自组织":
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
Input Evidence
|
|
143
|
+
↓
|
|
144
|
+
Memory State ←──────────────┐
|
|
145
|
+
↓ │
|
|
146
|
+
LEI Evaluation (八维熵) │
|
|
147
|
+
↓ │
|
|
148
|
+
Decay / Reinforcement ────────┘
|
|
149
|
+
↓
|
|
150
|
+
AuditChain (SHA256 链式追溯)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
这比单独的 memory store 更接近一个可被实验检验的**动态系统**:输入驱动状态、熵评估稳定性、衰减/强化回流状态、审计链保证来源可信。
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
111
157
|
## 架构对比
|
|
112
158
|
|
|
113
159
|
```
|
|
@@ -154,7 +200,8 @@ liquid-loop/
|
|
|
154
200
|
│ ├── __init__.py # 公共 API 导出
|
|
155
201
|
│ ├── workspace.py # 核心数据模型 + AuditChain + auto_classify + decay
|
|
156
202
|
│ ├── storage.py # JSON 持久化 + 审计链写入
|
|
157
|
-
│ ├── entropy.py #
|
|
203
|
+
│ ├── entropy.py # 八维熵值计算(含 CPE 三维)
|
|
204
|
+
│ ├── mesh/ # MESH v2 多智能体共识协议集成(validate_evidence / compute_cci / ...)
|
|
158
205
|
│ └── cli.py # Click CLI (11 命令)
|
|
159
206
|
├── examples/
|
|
160
207
|
│ └── quickstart.py
|
|
@@ -180,12 +227,15 @@ pytest -v
|
|
|
180
227
|
|
|
181
228
|
## 路线图
|
|
182
229
|
|
|
183
|
-
- [
|
|
184
|
-
- [ ]
|
|
185
|
-
- [ ]
|
|
230
|
+
- [x] 多 Agent 液环耦合(`liquid_loop.mesh` v2 共识协议,2026-07-15 落地)
|
|
231
|
+
- [ ] **[v0.8] 反证轨(Evidence Graph)**:Evidence 分 support / contradiction,一致增稳、冲突降稳,驱动 memory stability score(不再"一致即真")
|
|
232
|
+
- [ ] **[v0.8] 显式时间动力学**:`M(t+1) = M(t) + reinforcement − decay − contradiction_penalty`,让记忆成为"过程"而非"对象"(真正的液态循环)
|
|
233
|
+
- [ ] **[v0.8] 三实验**:E2 错误记忆恢复(核心)→ E3 多 agent 冲突(mesh 价值)→ E1 长期漂移(压力测试)
|
|
186
234
|
- [ ] LoCoMo / LongMemEval 基准对比
|
|
187
235
|
- [ ] 边缘端部署优化(<50KB)
|
|
188
236
|
|
|
237
|
+
> 零向量是液环的硬约束:一致性判定永不引入 embedding / 相似度(这正是液环要替代的方案)。
|
|
238
|
+
|
|
189
239
|
---
|
|
190
240
|
|
|
191
241
|
## 许可证
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""Liquid Loop — Workspace Cognitive Runtime v0.
|
|
2
|
-
__version__ = "0.
|
|
1
|
+
"""Liquid Loop — Workspace Cognitive Runtime v0.7.1 (CPE-fused, SEAL dual-opt, dual-track multi-agent, MESH v2 integration)"""
|
|
2
|
+
__version__ = "0.7.1"
|
|
3
3
|
|
|
4
4
|
from .workspace import (
|
|
5
5
|
WorkspaceState, Anchor, Evidence, Memory, Conflict,
|
|
6
6
|
AuditChain, CPERegularizer, SelfRefineEngine,
|
|
7
7
|
rhythmic_retrieve,
|
|
8
8
|
)
|
|
9
|
-
from .storage import load, save
|
|
9
|
+
from .storage import load, save, locked_state
|
|
10
10
|
from .entropy import calculate, calculate_detail, calculate as calculate_entropy
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
liquid_loop.mesh — 液环 MESH 进阶版(v2)共识协议集成
|
|
3
|
+
=====================================================
|
|
4
|
+
把"多智能体共识协议规范"从文档落地为可复用代码,作为 liquid-loop 的官方
|
|
5
|
+
MESH 集成层。零向量哲学:一致性判定走结构化精确相等 + 审计链哈希,绝不引入
|
|
6
|
+
任何 embedding / 相似度。
|
|
7
|
+
|
|
8
|
+
职责(详见 .v2):
|
|
9
|
+
- validate_evidence() agent 侧契约自检(结构化证据 schema)
|
|
10
|
+
- check_contract() 双向契约合规检查(身份 / 写 / 消费 / 冲突)
|
|
11
|
+
- compute_cci() 主体间性共识指数(记忆层)
|
|
12
|
+
- cognitive_health() 统一认知健康仪表盘(CCI / drift / H_e / P_mem)
|
|
13
|
+
- detect_conflict() 同锚点冲突证据检测
|
|
14
|
+
- fetch_state() 从 8790 REST /list 拉取当前状态
|
|
15
|
+
- main() 连接 8790 打印认知健康报告(CLI)
|
|
16
|
+
|
|
17
|
+
快速使用:
|
|
18
|
+
from liquid_loop.mesh import validate_evidence, compute_cci, cognitive_health
|
|
19
|
+
from liquid_loop.mesh import fetch_state, main
|
|
20
|
+
|
|
21
|
+
ok, errs = validate_evidence({"agent_id": "vera", "content": "..."})
|
|
22
|
+
health = cognitive_health(fetch_state())
|
|
23
|
+
"""
|
|
24
|
+
from .v2 import (
|
|
25
|
+
REGISTRY,
|
|
26
|
+
CLAIM_TYPES,
|
|
27
|
+
SCOPES,
|
|
28
|
+
Evidence,
|
|
29
|
+
validate_evidence,
|
|
30
|
+
check_contract,
|
|
31
|
+
compute_cci,
|
|
32
|
+
cognitive_health,
|
|
33
|
+
detect_conflict,
|
|
34
|
+
fetch_state,
|
|
35
|
+
main,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"REGISTRY",
|
|
40
|
+
"CLAIM_TYPES",
|
|
41
|
+
"SCOPES",
|
|
42
|
+
"Evidence",
|
|
43
|
+
"validate_evidence",
|
|
44
|
+
"check_contract",
|
|
45
|
+
"compute_cci",
|
|
46
|
+
"cognitive_health",
|
|
47
|
+
"detect_conflict",
|
|
48
|
+
"fetch_state",
|
|
49
|
+
"main",
|
|
50
|
+
]
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
liquid_loop_mesh_v2.py — 液环 MESH 进阶版(v2)参考实现
|
|
4
|
+
======================================================
|
|
5
|
+
把"共识协议规范"从文档落地为可复用代码。零向量哲学:一致性判定走
|
|
6
|
+
结构化精确相等 + 审计链哈希,绝不引入任何 embedding / 相似度。
|
|
7
|
+
|
|
8
|
+
职责:
|
|
9
|
+
1. validate_evidence() — agent 侧契约自检(结构化证据 schema)
|
|
10
|
+
2. check_contract() — 双向契约合规检查(身份/写/消费/冲突)
|
|
11
|
+
3. compute_cci() — 主体间性共识指数(记忆层)
|
|
12
|
+
4. cognitive_health() — 统一认知健康仪表盘(CCI / drift / H_e / P_mem)
|
|
13
|
+
5. detect_conflict() — 同锚点冲突证据检测
|
|
14
|
+
6. fetch_state() — 从 8790 REST /list 拉取当前状态
|
|
15
|
+
|
|
16
|
+
依赖:标准库 + 可选 liquid_loop(仅类型提示)。可直接 import 使用,
|
|
17
|
+
也可 `python3 liquid_loop_mesh_v2.py` 连 8790 打印健康报告。
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
import json
|
|
21
|
+
import sys
|
|
22
|
+
import urllib.request
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from typing import Optional
|
|
25
|
+
|
|
26
|
+
# ── agent-mesh 注册表(接入 agent 的唯一 id 白名单)──────────────
|
|
27
|
+
REGISTRY = {"workbuddy", "vera", "qwenpaw", "marvis", "parlant-ctrl", "cawpaw", "tabbit", "llama"}
|
|
28
|
+
|
|
29
|
+
CLAIM_TYPES = {"fact", "conclusion", "preference", "conflict"}
|
|
30
|
+
SCOPES = {"private", "consensus"}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# ── 1. 结构化证据 schema 校验 ──────────────────────────────────
|
|
34
|
+
@dataclass
|
|
35
|
+
class Evidence:
|
|
36
|
+
agent_id: str
|
|
37
|
+
content: str
|
|
38
|
+
category: str = "fact"
|
|
39
|
+
claim_type: str = "fact"
|
|
40
|
+
value: Optional[float] = None
|
|
41
|
+
session_id: str = ""
|
|
42
|
+
prev_hash: str = ""
|
|
43
|
+
id: str = ""
|
|
44
|
+
|
|
45
|
+
def to_dict(self) -> dict:
|
|
46
|
+
return {
|
|
47
|
+
"agent_id": self.agent_id,
|
|
48
|
+
"content": self.content,
|
|
49
|
+
"category": self.category,
|
|
50
|
+
"claim_type": self.claim_type,
|
|
51
|
+
"value": self.value,
|
|
52
|
+
"session_id": self.session_id,
|
|
53
|
+
"prev_hash": self.prev_hash,
|
|
54
|
+
"id": self.id,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def validate_evidence(ev: dict) -> tuple[bool, list[str]]:
|
|
59
|
+
"""agent 侧契约自检:返回 (ok, 错误列表)。"""
|
|
60
|
+
errs: list[str] = []
|
|
61
|
+
if not ev.get("agent_id"):
|
|
62
|
+
errs.append("agent_id 必填(共用机制要求声明写入者标识)")
|
|
63
|
+
elif ev["agent_id"] not in REGISTRY:
|
|
64
|
+
errs.append(f"agent_id '{ev['agent_id']}' 未在 mesh 注册表(禁止匿名污染)")
|
|
65
|
+
if not ev.get("content"):
|
|
66
|
+
errs.append("content 必填(一致性比对键)")
|
|
67
|
+
ct = ev.get("claim_type", "fact")
|
|
68
|
+
if ct not in CLAIM_TYPES:
|
|
69
|
+
errs.append(f"claim_type '{ct}' 非法,须为 {sorted(CLAIM_TYPES)}")
|
|
70
|
+
# content 精确相等判定 → 禁止任何 embedding/相似度
|
|
71
|
+
if ev.get("content") and not isinstance(ev["content"], str):
|
|
72
|
+
errs.append("content 必须为精确字符串(零向量一致性比对键)")
|
|
73
|
+
return (len(errs) == 0, errs)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# ── 2. 双向契约合规检查 ────────────────────────────────────────
|
|
77
|
+
def check_contract(agent_id: str, did_recall: bool, wrote_structured: bool) -> tuple[bool, list[str]]:
|
|
78
|
+
"""①身份 ②结构化写 ③主动消费 ④冲突响应(由 detect_conflict 触发)。"""
|
|
79
|
+
errs: list[str] = []
|
|
80
|
+
if agent_id not in REGISTRY:
|
|
81
|
+
errs.append("① 身份未声明/未注册")
|
|
82
|
+
if not wrote_structured:
|
|
83
|
+
errs.append("② 未结构化写入(缺 claim_type/session_id/prev_hash)")
|
|
84
|
+
if not did_recall:
|
|
85
|
+
errs.append("③ 会话未主动消费 consensus 视图(退化成孤岛)")
|
|
86
|
+
return (len(errs) == 0, errs)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# ── 3. CCI 主体间性共识指数(记忆层)────────────────────────────
|
|
90
|
+
def compute_cci(items: list[dict]) -> dict:
|
|
91
|
+
"""CCI_mem = |consensus| / (|consensus| + |private|)。"""
|
|
92
|
+
cons = [x for x in items if x.get("scope") == "consensus"]
|
|
93
|
+
priv = [x for x in items if x.get("scope") == "private"]
|
|
94
|
+
denom = len(cons) + len(priv)
|
|
95
|
+
cci = (len(cons) / denom) if denom else 0.0
|
|
96
|
+
# 共识强度 secondary:平均 contributors 基数
|
|
97
|
+
strengths = [len(x.get("contributors", [])) for x in cons] or [0]
|
|
98
|
+
avg_strength = sum(strengths) / len(strengths) if strengths else 0
|
|
99
|
+
return {
|
|
100
|
+
"cci": round(cci, 4),
|
|
101
|
+
"consensus": len(cons),
|
|
102
|
+
"private": len(priv),
|
|
103
|
+
"avg_contributors": round(avg_strength, 2),
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# ── 4. 统一认知健康仪表盘 ─────────────────────────────────────
|
|
108
|
+
def cognitive_health(items: list[dict], drift_rate: float = 0.0,
|
|
109
|
+
H_e: float = 0.0, P_mem: float = 0.0) -> dict:
|
|
110
|
+
cci = compute_cci(items)
|
|
111
|
+
evs = [x for x in items if x.get("type") == "evidence"]
|
|
112
|
+
from collections import Counter
|
|
113
|
+
by_agent = Counter(x.get("agent_id") for x in evs)
|
|
114
|
+
return {
|
|
115
|
+
"CCI": cci["cci"],
|
|
116
|
+
"consensus_crystals": cci["consensus"],
|
|
117
|
+
"private_crystals": cci["private"],
|
|
118
|
+
"drift_rate": drift_rate,
|
|
119
|
+
"H_e": H_e,
|
|
120
|
+
"P_mem": P_mem,
|
|
121
|
+
"total_evidence": len(evs),
|
|
122
|
+
"agents": dict(by_agent),
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# ── 5. 冲突检测 ───────────────────────────────────────────────
|
|
127
|
+
def detect_conflict(items: list[dict]) -> list[dict]:
|
|
128
|
+
"""同锚点下 claim_type=conflict 或同 content 反义 → 标记冲突 agent。"""
|
|
129
|
+
conflicts = []
|
|
130
|
+
by_cat = {}
|
|
131
|
+
for x in items:
|
|
132
|
+
if x.get("type") in ("evidence", "memory"):
|
|
133
|
+
by_cat.setdefault(x.get("category", "?"), []).append(x)
|
|
134
|
+
for cat, recs in by_cat.items():
|
|
135
|
+
conflict_recs = [r for r in recs if r.get("claim_type") == "conflict"]
|
|
136
|
+
if conflict_recs:
|
|
137
|
+
agents = sorted({r.get("agent_id") for r in conflict_recs if r.get("agent_id")})
|
|
138
|
+
conflicts.append({"anchor": cat, "conflict_agents": agents,
|
|
139
|
+
"kind": "explicit_conflict"})
|
|
140
|
+
return conflicts
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ── 6. 从 8790 拉取状态 ───────────────────────────────────────
|
|
144
|
+
def fetch_state(base: str = "http://127.0.0.1:8790") -> list[dict]:
|
|
145
|
+
req = urllib.request.Request(base + "/list", data=b"{}",
|
|
146
|
+
headers={"Content-Type": "application/json"})
|
|
147
|
+
with urllib.request.urlopen(req, timeout=5) as r:
|
|
148
|
+
d = json.load(r)
|
|
149
|
+
return d if isinstance(d, list) else d.get("result", d.get("items", []))
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# ── CLI:打印健康报告 ──────────────────────────────────────────
|
|
153
|
+
def main():
|
|
154
|
+
try:
|
|
155
|
+
items = fetch_state()
|
|
156
|
+
except Exception as e:
|
|
157
|
+
print(f"[ERR] 无法连接 8790: {e}")
|
|
158
|
+
sys.exit(1)
|
|
159
|
+
health = cognitive_health(items)
|
|
160
|
+
print("=== 液环 MESH v2 认知健康仪表盘 ===")
|
|
161
|
+
for k, v in health.items():
|
|
162
|
+
print(f" {k:18}: {v}")
|
|
163
|
+
conf = detect_conflict(items)
|
|
164
|
+
if conf:
|
|
165
|
+
print("\n=== 冲突锚点 ===")
|
|
166
|
+
for c in conf:
|
|
167
|
+
print(" ", c)
|
|
168
|
+
else:
|
|
169
|
+
print("\n[OK] 无显式冲突")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if __name__ == "__main__":
|
|
173
|
+
main()
|
|
@@ -36,7 +36,12 @@ def _file_lock(filepath: str, mode: str = "w"):
|
|
|
36
36
|
finally:
|
|
37
37
|
fcntl.flock(f, fcntl.LOCK_UN)
|
|
38
38
|
|
|
39
|
+
def _lock_path(workspace_root: Path) -> Path:
|
|
40
|
+
return _ensure_dir(workspace_root) / "state.lock"
|
|
41
|
+
|
|
42
|
+
|
|
39
43
|
def load(workspace_root: Path) -> WorkspaceState:
|
|
44
|
+
"""纯读取,无锁。并发安全由上层 locked_state 上下文保证。"""
|
|
40
45
|
path = _ensure_dir(workspace_root) / STATE_FILE
|
|
41
46
|
if not path.exists():
|
|
42
47
|
return WorkspaceState()
|
|
@@ -46,6 +51,7 @@ def load(workspace_root: Path) -> WorkspaceState:
|
|
|
46
51
|
|
|
47
52
|
|
|
48
53
|
def save(state: WorkspaceState, workspace_root: Path):
|
|
54
|
+
"""原子写(temp+rename):崩溃永不留下半截文件。锁由 locked_state 持有。"""
|
|
49
55
|
state.updated_at = now()
|
|
50
56
|
path = _ensure_dir(workspace_root) / STATE_FILE
|
|
51
57
|
# 审计链:记录并回写哈希
|
|
@@ -59,8 +65,28 @@ def save(state: WorkspaceState, workspace_root: Path):
|
|
|
59
65
|
data = asdict(state)
|
|
60
66
|
# overlap_cache 仅为运行时熵计算缓存,键为 tuple,不可 JSON 序列化,且不具持久价值
|
|
61
67
|
data.pop("overlap_cache", None)
|
|
62
|
-
|
|
68
|
+
tmp = path.with_suffix(".tmp")
|
|
69
|
+
with open(tmp, "w", encoding="utf-8") as f:
|
|
63
70
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
71
|
+
f.flush()
|
|
72
|
+
os.fsync(f.fileno())
|
|
73
|
+
os.replace(tmp, path) # POSIX 原子替换,读端永不看到半截文件
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@contextmanager
|
|
77
|
+
def locked_state(workspace_root: Path):
|
|
78
|
+
"""单一锁层:排他锁跨 load→modify→save 整段,根除并发丢写(P0)。
|
|
79
|
+
跨进程安全(fcntl 建议锁);server 与批量喂入脚本共用同一把锁。"""
|
|
80
|
+
d = _ensure_dir(workspace_root)
|
|
81
|
+
lk = open(d / "state.lock", "w")
|
|
82
|
+
fcntl.flock(lk, fcntl.LOCK_EX)
|
|
83
|
+
try:
|
|
84
|
+
st = load(workspace_root)
|
|
85
|
+
yield st
|
|
86
|
+
save(st, workspace_root)
|
|
87
|
+
finally:
|
|
88
|
+
fcntl.flock(lk, fcntl.LOCK_UN)
|
|
89
|
+
lk.close()
|
|
64
90
|
|
|
65
91
|
|
|
66
92
|
def _from_dict(data: dict) -> WorkspaceState:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from dataclasses import dataclass, field
|
|
2
4
|
from datetime import datetime, timezone
|
|
3
5
|
from typing import Optional, List, Dict, Any
|
|
@@ -153,6 +155,7 @@ class Evidence:
|
|
|
153
155
|
weight: float = 1.0
|
|
154
156
|
quality: str = "normal"
|
|
155
157
|
archived: bool = False # 预算超额冷归档标记(PEEK 落地,零丢失)
|
|
158
|
+
agent_id: str = "" # 多智能体共用:写入者标识(共用机制,缺省=legacy/单实例)
|
|
156
159
|
|
|
157
160
|
|
|
158
161
|
@dataclass
|
|
@@ -162,6 +165,8 @@ class Memory:
|
|
|
162
165
|
formed_at: str = field(default_factory=now)
|
|
163
166
|
evidence_ids: list[str] = field(default_factory=list)
|
|
164
167
|
confidence: float = 0.0
|
|
168
|
+
scope: str = "private" # 结晶来源: private(同 agent≥2一致) / consensus(跨 distinct owner≥2一致)
|
|
169
|
+
contributors: list[str] = field(default_factory=list) # 参与成核的 agent_id 列表
|
|
165
170
|
|
|
166
171
|
|
|
167
172
|
@dataclass
|
|
@@ -243,10 +248,17 @@ class WorkspaceState:
|
|
|
243
248
|
self.updated_at = now()
|
|
244
249
|
return a
|
|
245
250
|
|
|
246
|
-
def add_evidence(self, anchor
|
|
251
|
+
def add_evidence(self, anchor, content: str, quality: float = 1.0, agent_id: str = "",
|
|
252
|
+
dedup: bool = False) -> Optional[Evidence]:
|
|
247
253
|
"""向指定锚点添加一条证据。
|
|
248
254
|
|
|
249
255
|
anchor 参数兼容:锚点名称(str) | 锚点ID(str) | Anchor对象
|
|
256
|
+
agent_id:多智能体共用写入者标识(缺省空=legacy/单实例)
|
|
257
|
+
dedup:幂等去重开关(默认 False)。
|
|
258
|
+
- False(默认,核心语义):同内容可重复写入——"≥2 条一致证据自动结晶"依赖此行为
|
|
259
|
+
(README quickstart / 双轨成核 / 理论定义)。
|
|
260
|
+
- True(mesh/API 层显式启用):同锚点+同内容+同 agent 已存在则复用,防网络重试/高频喂入膨胀。
|
|
261
|
+
幂等应由 mesh/API 层按需开启,核心模型默认不吞掉"重复观察"这一结晶信号。
|
|
250
262
|
"""
|
|
251
263
|
target = None
|
|
252
264
|
if isinstance(anchor, Anchor):
|
|
@@ -258,9 +270,14 @@ class WorkspaceState:
|
|
|
258
270
|
target = next((a for a in self.anchors if a.id == anchor), None)
|
|
259
271
|
if not target:
|
|
260
272
|
return None
|
|
273
|
+
# 幂等去重(仅当 dedup=True):同锚点+同内容+同 agent 已存在则复用
|
|
274
|
+
if dedup:
|
|
275
|
+
for ex in self.evidences:
|
|
276
|
+
if ex.anchor_id == target.id and ex.content == content and ex.agent_id == agent_id:
|
|
277
|
+
return ex
|
|
261
278
|
e = Evidence(
|
|
262
279
|
id=uid(), anchor_id=target.id, content=content,
|
|
263
|
-
quality=quality, timestamp=now(),
|
|
280
|
+
quality=quality, timestamp=now(), agent_id=agent_id,
|
|
264
281
|
)
|
|
265
282
|
self.evidences.append(e)
|
|
266
283
|
target.evidence_ids.append(e.id)
|
|
@@ -289,31 +306,68 @@ class WorkspaceState:
|
|
|
289
306
|
e.weight = max(e.weight * 0.95, 0.1)
|
|
290
307
|
|
|
291
308
|
def _nucleate(self, anchor_id: str):
|
|
292
|
-
"""
|
|
309
|
+
"""双轨成核(多智能体共用机制):
|
|
310
|
+
|
|
311
|
+
- private 轨:同一 agent_id 下 >= 2 条一致证据 -> scope=private 结晶
|
|
312
|
+
- consensus 轨:同一 content 被 >= 2 个 distinct agent_id 证据支持 -> scope=consensus 结晶
|
|
293
313
|
|
|
294
|
-
|
|
295
|
-
|
|
314
|
+
复合键 (anchor_id, content, scope) 防跨锚点/跨轨污染。
|
|
315
|
+
兼容 legacy:agent_id 为空视为单实例私有(走 private 轨,contributors=["legacy"])。
|
|
296
316
|
"""
|
|
297
317
|
group = [e for e in self.evidences if e.anchor_id == anchor_id]
|
|
298
318
|
if len(group) < 2:
|
|
299
319
|
return
|
|
300
|
-
#
|
|
301
|
-
|
|
320
|
+
# 已结晶键集合(复合键判定,杜绝跨锚点/跨轨污染)
|
|
321
|
+
crystallized_keys: set = set()
|
|
302
322
|
for m in self.memories:
|
|
303
323
|
for eid in m.evidence_ids:
|
|
304
324
|
ev = next((e for e in self.evidences if e.id == eid), None)
|
|
305
325
|
if ev is not None and ev.anchor_id == anchor_id:
|
|
306
|
-
|
|
326
|
+
crystallized_keys.add((m.content, m.scope))
|
|
307
327
|
break
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
328
|
+
from collections import defaultdict
|
|
329
|
+
# ── private 轨:按 agent_id 分组,组内同 content >= 2 ──
|
|
330
|
+
by_agent: dict = defaultdict(list)
|
|
331
|
+
for e in group:
|
|
332
|
+
by_agent[e.agent_id if e.agent_id else "legacy"].append(e)
|
|
333
|
+
for owner, evs in by_agent.items():
|
|
334
|
+
content_counts = Counter(e.content for e in evs)
|
|
335
|
+
for content, count in content_counts.items():
|
|
336
|
+
if count >= 2 and (content, "private") not in crystallized_keys:
|
|
337
|
+
evidence_ids = [e.id for e in evs if e.content == content]
|
|
338
|
+
confidence = min(count / len(evs), 1.0)
|
|
339
|
+
self.memories.append(Memory(
|
|
340
|
+
content=content,
|
|
341
|
+
evidence_ids=evidence_ids,
|
|
342
|
+
confidence=confidence,
|
|
343
|
+
scope="private",
|
|
344
|
+
contributors=[owner],
|
|
345
|
+
))
|
|
346
|
+
# ── consensus 轨:跨 distinct owner 同 content >= 2 ──
|
|
347
|
+
owners_by_content: dict = defaultdict(set)
|
|
348
|
+
for e in group:
|
|
349
|
+
if not e.agent_id:
|
|
350
|
+
continue # legacy 不参与共识轨(无法跨主体)
|
|
351
|
+
owners_by_content[e.content].add(e.agent_id)
|
|
352
|
+
for content, owners in owners_by_content.items():
|
|
353
|
+
if len(owners) < 2:
|
|
354
|
+
continue
|
|
355
|
+
# 已存在的共识结晶:把新一致方并入 contributors(动态扩展,支撑三方+ CCI 计量)
|
|
356
|
+
existing = next((m for m in self.memories if m.scope == "consensus" and m.content == content), None)
|
|
357
|
+
if existing is not None:
|
|
358
|
+
merged = set(existing.contributors) | owners
|
|
359
|
+
if merged != set(existing.contributors):
|
|
360
|
+
existing.contributors = sorted(merged)
|
|
361
|
+
continue
|
|
362
|
+
if (content, "consensus") not in crystallized_keys:
|
|
363
|
+
evidence_ids = [e.id for e in group if e.content == content and e.agent_id in owners]
|
|
364
|
+
confidence = min(len(owners) / 2.0, 1.0)
|
|
313
365
|
self.memories.append(Memory(
|
|
314
366
|
content=content,
|
|
315
367
|
evidence_ids=evidence_ids,
|
|
316
368
|
confidence=confidence,
|
|
369
|
+
scope="consensus",
|
|
370
|
+
contributors=sorted(owners),
|
|
317
371
|
))
|
|
318
372
|
# 成核后触发自动描述回流(仅当描述为空)
|
|
319
373
|
self._auto_describe_anchor(anchor_id)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: liquid-loop
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Self-Organizing Cognitive Memory for AI Agents — Liquid Loop theory implementation
|
|
5
5
|
Author: fishbook0001
|
|
6
6
|
Maintainer: fishbook0001
|
|
@@ -72,7 +72,7 @@ Dynamic: license-file
|
|
|
72
72
|
| **Anchor** 锚点 | 晶种 | 认知关注点,有稳定性值 s ∈ [0,1] |
|
|
73
73
|
| **Evidence** 证据 | 附着粒子 | 锚点下的具体观察,权重指数衰减 w×0.95ᵗ |
|
|
74
74
|
| **Memory** 结晶 | 结晶体 | 2+ 条一致 Evidence 自动凝聚,有置信度 c |
|
|
75
|
-
| **Entropy** 熵值 | 流体无序度 | 八维加权(锚点漂移 / 冲突密度 / 碎片 / 活跃间隔 / 价值衰减 / 锚定强度 / CPE 三维) |
|
|
75
|
+
| **Entropy** 熵值 (LEI) | 流体无序度 | 八维加权(锚点漂移 / 冲突密度 / 碎片 / 活跃间隔 / 价值衰减 / 锚定强度 / CPE 三维) |
|
|
76
76
|
|
|
77
77
|
**状态判定:**
|
|
78
78
|
```
|
|
@@ -81,6 +81,12 @@ YELLOW (0.3 ≤ entropy < 0.6) — 需关注
|
|
|
81
81
|
RED (entropy ≥ 0.6) — 需清理
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
> **关于 "Entropy" 的语义澄清 — Liquid Entropy Index (LEI)**
|
|
85
|
+
>
|
|
86
|
+
> 本项目中的 `entropy` 是 **Liquid Entropy Index (LEI): a system-stability deviation metric, inspired by entropy but NOT equivalent to thermodynamic entropy.**
|
|
87
|
+
> 它不是物理熵 `S = -k Σ pᵢ log pᵢ`,而是对**系统状态偏离稳定流形程度**的综合度量——由八个可解释分量人工加权而成(锚点漂移 / 冲突密度 / 证据碎片 / 活跃间隔 / 价值衰减 / 锚定强度 + CPE 三维:回顾性衰退 / 策略漂移 / 泛化崩塌)。
|
|
88
|
+
> 代码层函数名保留 `calculate()`(历史连续性);文档 / 论文层一律以 **LEI** 指称,避免与热力学熵混淆。
|
|
89
|
+
|
|
84
90
|
---
|
|
85
91
|
|
|
86
92
|
## 快速开始
|
|
@@ -93,7 +99,7 @@ pip install liquid-loop
|
|
|
93
99
|
|
|
94
100
|
### 3 分钟上手
|
|
95
101
|
```python
|
|
96
|
-
from liquid_loop import WorkspaceState, load, save,
|
|
102
|
+
from liquid_loop import WorkspaceState, load, save, calculate
|
|
97
103
|
|
|
98
104
|
# 1. 创建/加载工作区
|
|
99
105
|
state = WorkspaceState() # 或 load(Path("."))
|
|
@@ -111,7 +117,7 @@ for m in state.memories:
|
|
|
111
117
|
print(f"结晶: {m.content[:50]}... (置信度={m.confidence:.2f})")
|
|
112
118
|
|
|
113
119
|
# 5. 监控认知健康
|
|
114
|
-
entropy =
|
|
120
|
+
entropy = calculate(state)
|
|
115
121
|
print(f"熵值: {entropy:.4f} → {'🟢GREEN' if entropy < 0.3 else '🟡YELLOW' if entropy < 0.6 else '🔴RED'}")
|
|
116
122
|
|
|
117
123
|
# 6. 持久化
|
|
@@ -147,6 +153,46 @@ liquid-loop snapshot
|
|
|
147
153
|
|
|
148
154
|
---
|
|
149
155
|
|
|
156
|
+
## MESH 集成(多智能体共识)
|
|
157
|
+
|
|
158
|
+
液环从 v0.7.0 起内置官方 MESH 集成 `liquid_loop.mesh`,把"多智能体共识协议"落地为可复用代码,作为 agent-mesh 节点的标准接入层。
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from liquid_loop.mesh import validate_evidence, compute_cci, cognitive_health, fetch_state
|
|
162
|
+
|
|
163
|
+
# agent 写入前契约自检(零向量:content 必须精确字符串,禁 embedding)
|
|
164
|
+
ok, errs = validate_evidence({"agent_id": "vera", "content": "用户偏好简洁输出"})
|
|
165
|
+
|
|
166
|
+
# 从 8790 拉取记忆状态,算主体间性共识指数 CCI
|
|
167
|
+
items = fetch_state("http://127.0.0.1:8790")
|
|
168
|
+
health = cognitive_health(items)
|
|
169
|
+
print(health["CCI"], health["consensus_crystals"])
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
零向量哲学:一致性判定走**结构化精确相等 + 审计链哈希**,绝不引入任何 embedding / 相似度。规范详见 `mesh/liquid_loop_mesh_v2_spec.md`。
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 定位:Self-Regulating Persistent Memory Dynamics
|
|
177
|
+
|
|
178
|
+
液环的本质不是"AI 意识",而是一套 **agent 系统的自调节持久记忆动力学(Self-Regulating Persistent Memory Dynamics for Agent Systems)**。`AuditChain + LEI(Entropy) + Memory decay` 三者组合形成闭环,使记忆从"外部管理"转向"内部自组织":
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
Input Evidence
|
|
182
|
+
↓
|
|
183
|
+
Memory State ←──────────────┐
|
|
184
|
+
↓ │
|
|
185
|
+
LEI Evaluation (八维熵) │
|
|
186
|
+
↓ │
|
|
187
|
+
Decay / Reinforcement ────────┘
|
|
188
|
+
↓
|
|
189
|
+
AuditChain (SHA256 链式追溯)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
这比单独的 memory store 更接近一个可被实验检验的**动态系统**:输入驱动状态、熵评估稳定性、衰减/强化回流状态、审计链保证来源可信。
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
150
196
|
## 架构对比
|
|
151
197
|
|
|
152
198
|
```
|
|
@@ -193,7 +239,8 @@ liquid-loop/
|
|
|
193
239
|
│ ├── __init__.py # 公共 API 导出
|
|
194
240
|
│ ├── workspace.py # 核心数据模型 + AuditChain + auto_classify + decay
|
|
195
241
|
│ ├── storage.py # JSON 持久化 + 审计链写入
|
|
196
|
-
│ ├── entropy.py #
|
|
242
|
+
│ ├── entropy.py # 八维熵值计算(含 CPE 三维)
|
|
243
|
+
│ ├── mesh/ # MESH v2 多智能体共识协议集成(validate_evidence / compute_cci / ...)
|
|
197
244
|
│ └── cli.py # Click CLI (11 命令)
|
|
198
245
|
├── examples/
|
|
199
246
|
│ └── quickstart.py
|
|
@@ -219,12 +266,15 @@ pytest -v
|
|
|
219
266
|
|
|
220
267
|
## 路线图
|
|
221
268
|
|
|
222
|
-
- [
|
|
223
|
-
- [ ]
|
|
224
|
-
- [ ]
|
|
269
|
+
- [x] 多 Agent 液环耦合(`liquid_loop.mesh` v2 共识协议,2026-07-15 落地)
|
|
270
|
+
- [ ] **[v0.8] 反证轨(Evidence Graph)**:Evidence 分 support / contradiction,一致增稳、冲突降稳,驱动 memory stability score(不再"一致即真")
|
|
271
|
+
- [ ] **[v0.8] 显式时间动力学**:`M(t+1) = M(t) + reinforcement − decay − contradiction_penalty`,让记忆成为"过程"而非"对象"(真正的液态循环)
|
|
272
|
+
- [ ] **[v0.8] 三实验**:E2 错误记忆恢复(核心)→ E3 多 agent 冲突(mesh 价值)→ E1 长期漂移(压力测试)
|
|
225
273
|
- [ ] LoCoMo / LongMemEval 基准对比
|
|
226
274
|
- [ ] 边缘端部署优化(<50KB)
|
|
227
275
|
|
|
276
|
+
> 零向量是液环的硬约束:一致性判定永不引入 embedding / 相似度(这正是液环要替代的方案)。
|
|
277
|
+
|
|
228
278
|
---
|
|
229
279
|
|
|
230
280
|
## 许可证
|
|
@@ -14,7 +14,11 @@ liquid_loop.egg-info/dependency_links.txt
|
|
|
14
14
|
liquid_loop.egg-info/entry_points.txt
|
|
15
15
|
liquid_loop.egg-info/requires.txt
|
|
16
16
|
liquid_loop.egg-info/top_level.txt
|
|
17
|
+
liquid_loop/mesh/__init__.py
|
|
18
|
+
liquid_loop/mesh/v2.py
|
|
19
|
+
tests/test_consensus_expansion.py
|
|
17
20
|
tests/test_entropy.py
|
|
21
|
+
tests/test_nucleate_dual_track.py
|
|
18
22
|
tests/test_peek_seal.py
|
|
19
23
|
tests/test_seal_persistence.py
|
|
20
24
|
tests/test_self_evolve.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "liquid-loop"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.1"
|
|
8
8
|
description = "Self-Organizing Cognitive Memory for AI Agents — Liquid Loop theory implementation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""共识结晶 contributors 随新一致方动态扩展(三方+ CCI 计量)。"""
|
|
2
|
+
from liquid_loop import WorkspaceState
|
|
3
|
+
from liquid_loop.workspace import Anchor, Evidence, Memory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _add(st, name, content, agent_id):
|
|
7
|
+
a = next((x for x in st.anchors if x.name == name), None)
|
|
8
|
+
if a is None:
|
|
9
|
+
a = st.add_anchor(name)
|
|
10
|
+
e = Evidence(content=content, anchor_id=a.id, agent_id=agent_id)
|
|
11
|
+
st.add_evidence(a, content, agent_id=agent_id)
|
|
12
|
+
return a
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_consensus_expands_with_third_agent():
|
|
16
|
+
st = WorkspaceState()
|
|
17
|
+
# qwenpaw + vera 先达成共识
|
|
18
|
+
_add(st, "液环", "液环是零向量记忆", "qwenpaw")
|
|
19
|
+
_add(st, "液环", "液环是零向量记忆", "qwenpaw") # qwenpaw >=2 -> private
|
|
20
|
+
_add(st, "液环", "液环是零向量记忆", "vera") # +vera -> consensus[qwenpaw,vera]
|
|
21
|
+
cons = next(m for m in st.memories if m.scope == "consensus")
|
|
22
|
+
assert cons.contributors == ["qwenpaw", "vera"], cons.contributors
|
|
23
|
+
# marvis 也写同内容 -> 应并入三方共识
|
|
24
|
+
_add(st, "液环", "液环是零向量记忆", "marvis")
|
|
25
|
+
cons = next(m for m in st.memories if m.scope == "consensus")
|
|
26
|
+
assert cons.contributors == ["marvis", "qwenpaw", "vera"], cons.contributors
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_consensus_no_duplicate_on_repeat():
|
|
30
|
+
st = WorkspaceState()
|
|
31
|
+
_add(st, "fact", "X", "a")
|
|
32
|
+
_add(st, "fact", "X", "a") # private[a]
|
|
33
|
+
_add(st, "fact", "X", "b") # consensus[a,b]
|
|
34
|
+
_add(st, "fact", "X", "b") # b 重复,不应扩
|
|
35
|
+
cons = next(m for m in st.memories if m.scope == "consensus")
|
|
36
|
+
assert cons.contributors == ["a", "b"], cons.contributors
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_private_untouched_by_consensus_expansion():
|
|
40
|
+
st = WorkspaceState()
|
|
41
|
+
_add(st, "fact", "Y", "qwenpaw")
|
|
42
|
+
_add(st, "fact", "Y", "qwenpaw") # private[qwenpaw]
|
|
43
|
+
_add(st, "fact", "Y", "vera") # consensus
|
|
44
|
+
priv = [m for m in st.memories if m.scope == "private"]
|
|
45
|
+
assert priv and priv[0].contributors == ["qwenpaw"], priv
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""双轨成核 + 防污染回归测试(多智能体共用机制)。
|
|
2
|
+
|
|
3
|
+
锁住行为:
|
|
4
|
+
- private 轨:同一 agent_id 内 >= 2 一致证据 -> scope=private
|
|
5
|
+
- consensus 轨:同一 content 跨 >= 2 distinct agent_id -> scope=consensus
|
|
6
|
+
- 防污染:不同 agent 不互相成私有晶;跨锚点同 content 不合并;复合键 (anchor,content,scope)
|
|
7
|
+
"""
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
12
|
+
|
|
13
|
+
from liquid_loop.workspace import WorkspaceState
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _add(st, name, content, agent_id=""):
|
|
17
|
+
a = next((x for x in st.anchors if x.name == name), None)
|
|
18
|
+
if a is None:
|
|
19
|
+
a = st.add_anchor(name)
|
|
20
|
+
return st.add_evidence(a, content, agent_id=agent_id)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_private_nucleation_same_agent():
|
|
24
|
+
st = WorkspaceState()
|
|
25
|
+
_add(st, "topic", "液环是零向量记忆", agent_id="qwenpaw")
|
|
26
|
+
_add(st, "topic", "液环是零向量记忆", agent_id="qwenpaw")
|
|
27
|
+
priv = [m for m in st.memories if m.scope == "private"]
|
|
28
|
+
cons = [m for m in st.memories if m.scope == "consensus"]
|
|
29
|
+
assert len(priv) == 1
|
|
30
|
+
assert priv[0].contributors == ["qwenpaw"]
|
|
31
|
+
assert len(cons) == 0
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_private_isolation_diff_agents():
|
|
35
|
+
st = WorkspaceState()
|
|
36
|
+
_add(st, "topic", "同一结论", agent_id="qwenpaw")
|
|
37
|
+
_add(st, "topic", "同一结论", agent_id="vera")
|
|
38
|
+
# 各 agent 内仅 1 条 -> 不 privately 成核
|
|
39
|
+
assert all(m.scope != "private" for m in st.memories)
|
|
40
|
+
# 但跨 2 distinct owner -> consensus 成核
|
|
41
|
+
cons = [m for m in st.memories if m.scope == "consensus"]
|
|
42
|
+
assert len(cons) == 1
|
|
43
|
+
assert set(cons[0].contributors) == {"qwenpaw", "vera"}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_consensus_requires_distinct_owner():
|
|
47
|
+
st = WorkspaceState()
|
|
48
|
+
_add(st, "topic", "共识结论", agent_id="qwenpaw")
|
|
49
|
+
_add(st, "topic", "共识结论", agent_id="qwenpaw") # 同 owner 重复
|
|
50
|
+
# 同 owner 2 条 -> private,但不该有 consensus(只有 1 个 owner)
|
|
51
|
+
cons = [m for m in st.memories if m.scope == "consensus"]
|
|
52
|
+
assert len(cons) == 0
|
|
53
|
+
priv = [m for m in st.memories if m.scope == "private"]
|
|
54
|
+
assert len(priv) == 1
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_cross_anchor_no_pollution():
|
|
58
|
+
st = WorkspaceState()
|
|
59
|
+
_add(st, "A", "X", agent_id="qwenpaw")
|
|
60
|
+
_add(st, "A", "X", agent_id="qwenpaw")
|
|
61
|
+
_add(st, "B", "X", agent_id="qwenpaw")
|
|
62
|
+
_add(st, "B", "X", agent_id="qwenpaw")
|
|
63
|
+
# 两个锚点各成 1 个 private 晶,不合并
|
|
64
|
+
priv = [m for m in st.memories if m.scope == "private"]
|
|
65
|
+
assert len(priv) == 2
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_legacy_compat_no_agent_id():
|
|
69
|
+
st = WorkspaceState()
|
|
70
|
+
_add(st, "topic", "legacy 内容", agent_id="")
|
|
71
|
+
_add(st, "topic", "legacy 内容", agent_id="")
|
|
72
|
+
priv = [m for m in st.memories if m.scope == "private"]
|
|
73
|
+
assert len(priv) == 1
|
|
74
|
+
assert priv[0].contributors == ["legacy"]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_dual_track_coexist():
|
|
78
|
+
st = WorkspaceState()
|
|
79
|
+
# 私有:qwenpaw 内 2 条独有结论
|
|
80
|
+
_add(st, "T", "qwenpaw 私有结论", agent_id="qwenpaw")
|
|
81
|
+
_add(st, "T", "qwenpaw 私有结论", agent_id="qwenpaw")
|
|
82
|
+
# 共识:qwenpaw + vera 各 1 条共享结论
|
|
83
|
+
_add(st, "T", "共享结论", agent_id="qwenpaw")
|
|
84
|
+
_add(st, "T", "共享结论", agent_id="vera")
|
|
85
|
+
priv = [m for m in st.memories if m.scope == "private"]
|
|
86
|
+
cons = [m for m in st.memories if m.scope == "consensus"]
|
|
87
|
+
assert len(priv) == 1 and priv[0].contributors == ["qwenpaw"]
|
|
88
|
+
assert len(cons) == 1 and set(cons[0].contributors) == {"qwenpaw", "vera"}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_no_pollution_between_agents_private():
|
|
92
|
+
st = WorkspaceState()
|
|
93
|
+
_add(st, "T", "结论A", agent_id="qwenpaw")
|
|
94
|
+
_add(st, "T", "结论A", agent_id="qwenpaw")
|
|
95
|
+
_add(st, "T", "结论A", agent_id="vera") # vera 只有 1 条 -> 不成私有
|
|
96
|
+
priv = [m for m in st.memories if m.scope == "private"]
|
|
97
|
+
cons = [m for m in st.memories if m.scope == "consensus"]
|
|
98
|
+
# qwenpaw 私有 1 晶;vera 仅 1 条不足私有;二者合计 2 distinct owner -> consensus 1 晶
|
|
99
|
+
assert len(priv) == 1 and priv[0].contributors == ["qwenpaw"]
|
|
100
|
+
assert len(cons) == 1 and set(cons[0].contributors) == {"qwenpaw", "vera"}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_storage_roundtrip_agent_id_scope(tmp_path):
|
|
104
|
+
"""持久化往返:agent_id / scope / contributors 必须无损保存加载。"""
|
|
105
|
+
from liquid_loop import storage
|
|
106
|
+
st = WorkspaceState()
|
|
107
|
+
_add(st, "T", "X", agent_id="qwenpaw")
|
|
108
|
+
_add(st, "T", "X", agent_id="qwenpaw")
|
|
109
|
+
storage.save(st, tmp_path)
|
|
110
|
+
st2 = storage.load(tmp_path)
|
|
111
|
+
assert len(st2.memories) == 1
|
|
112
|
+
m = st2.memories[0]
|
|
113
|
+
assert m.scope == "private"
|
|
114
|
+
assert m.contributors == ["qwenpaw"]
|
|
115
|
+
assert st2.evidences[0].agent_id == "qwenpaw"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|