- commit
- 423d812
- parent
- bcde56d
- author
- im_wower
- date
- 2026-04-01 09:58:10 +0800 CST
integration phase2: PendingSignal信号队列移植(来自A) — 12/12 tests pass
3 files changed,
+143,
-50
+2,
-2
1@@ -1,7 +1,7 @@
2 """CIE — Cognitive Inference Engine"""
3 from .graph import Graph, Node, Edge
4-from .state import CIEState, AttentionPool
5+from .state import CIEState, AttentionPool, PendingSignal
6 from .dynamics import Dynamics
7 from .runtime import CIERuntime
8
9-__all__ = ['Graph', 'Node', 'Edge', 'CIEState', 'AttentionPool', 'Dynamics', 'CIERuntime']
10+__all__ = ['Graph', 'Node', 'Edge', 'CIEState', 'AttentionPool', 'PendingSignal', 'Dynamics', 'CIERuntime']
+118,
-48
1@@ -9,7 +9,7 @@ import random
2 import math
3 from typing import Optional
4 from .graph import Graph
5-from .state import CIEState
6+from .state import CIEState, PendingSignal
7 from .dynamics import Dynamics
8
9
10@@ -32,7 +32,6 @@ class CIERuntime:
11 self._last_output: Optional[dict] = None
12
13 # ── 回灌标记 ──
14- self._feedback_pending = False
15
16 # ──────────────────────────────────────
17 # §5.1 ingest — 接收输入,注入图中
18@@ -55,8 +54,7 @@ class CIERuntime:
19 # ── 输出即输入回灌 ──
20 if self._last_output is not None and self._feedback_pending:
21 self._feedback_loop(self._last_output)
22- self._feedback_pending = False
23-
24+
25 # ── 解析输入为 token 序列 ──
26 if isinstance(input_data, str):
27 tokens = list(input_data)
28@@ -113,11 +111,75 @@ class CIERuntime:
29 def step(self, n: int = 1):
30 """
31 推进 n 步内部动力学演化。
32- 必须真实改变内部状态。
33+ 第一步先消费所有 pending_signals,然后跑动力学。
34 """
35- for _ in range(n):
36+ for i in range(n):
37+ # 第一步消费所有信号
38+ if i == 0:
39+ self._consume_signals()
40 self.dynamics.step()
41
42+ def _consume_signals(self):
43+ """消费所有排队的信号——来自 ingest/emit/feedback"""
44+ signals = list(self.state.pending_signals)
45+ self.state.pending_signals.clear()
46+
47+ for signal in signals:
48+ self._apply_signal(signal)
49+
50+ def _apply_signal(self, signal):
51+ """应用一个信号到图上"""
52+ tokens = signal.tokens
53+ if not tokens:
54+ return
55+
56+ # ── 注入节点和激活 ──
57+ for token in tokens:
58+ if not self.graph.has_node(token):
59+ self.graph.add_node(token, label=token)
60+ self.state.init_node(token, phi_val=self.rng.gauss(0.0, 0.1))
61+
62+ inject_amount = (100.0 / max(len(tokens), 1) * 0.5) * signal.strength
63+ if signal.polarity >= 0:
64+ self.state.activate(token, inject_amount)
65+ else:
66+ # 负极性:衰减
67+ self.state.phi[token] = self.state.phi.get(token, 0.0) * 0.5
68+ self.state.weaken_confidence(token, amount=abs(signal.strength))
69+
70+ # ── 建立 bigram 边(非对称) ──
71+ for i in range(len(tokens) - 1):
72+ src, dst = tokens[i], tokens[i + 1]
73+ existing_w = self.graph.get_edge_weight(src, dst)
74+ asym = self.rng.gauss(0.0, 0.1)
75+ increment = 1.0 / (1.0 + existing_w * 0.1) * signal.strength
76+ self.graph.add_edge(
77+ src, dst,
78+ weight=existing_w + increment + abs(asym),
79+ bwd_weight=existing_w + increment - abs(asym) * 0.5,
80+ edge_type='bigram'
81+ )
82+ self.state.update_confidence(src, 0, amount=0.5 * signal.strength)
83+ self.state.update_confidence(dst, 1, amount=0.5 * signal.strength)
84+
85+ # ── 锚点注入 ──
86+ for anchor in signal.anchor_tokens:
87+ if not self.graph.has_node(anchor):
88+ self.graph.add_node(anchor, label=anchor)
89+ self.state.init_node(anchor, phi_val=1.0)
90+ self.state.update_confidence(anchor, 2, amount=10.0 * signal.strength)
91+ self.state.phi[anchor] = self.state.phi.get(anchor, 0.0) + 1.0 * signal.strength
92+
93+ # ── 回灌信号额外处理 ──
94+ if signal.source == "emit":
95+ # 回灌的激活量较弱
96+ for token in tokens:
97+ mu_val = signal.metadata.get("mu_" + token, 0.0)
98+ feedback_amount = mu_val * 0.05
99+ if feedback_amount > 0.001 and self.graph.has_node(token):
100+ self.state.activate(token, feedback_amount)
101+ self.state.phi[token] = self.state.phi.get(token, 0.0) + feedback_amount * 0.01
102+
103 # ──────────────────────────────────────
104 # §5.3 emit — 生成输出
105 # ──────────────────────────────────────
106@@ -168,6 +230,20 @@ class CIERuntime:
107 'active_count': len(self.state.active_region),
108 }
109
110+ # 创建回灌信号排队
111+ metadata = {"mode": output["mode"]}
112+ for item in output.get("activated", []):
113+ metadata["mu_" + item["node"]] = item.get("mu", 0.0)
114+
115+ feedback_signal = PendingSignal(
116+ source="emit",
117+ tokens=[item["node"] for item in output.get("activated", [])[:5]],
118+ strength={"full": 0.5, "degraded": 0.3, "minimal": 0.1}.get(output["mode"], 0.1),
119+ polarity=1,
120+ metadata=metadata,
121+ )
122+ self.state.pending_signals.append(feedback_signal)
123+
124 self._last_output = output
125 self._output_buffer.append(output)
126 return output
127@@ -178,50 +254,48 @@ class CIERuntime:
128
129 def commit_feedback(self, feedback: dict):
130 """
131- 把反馈写回系统——经验沉积、技能带修正、能力核慢更新。
132-
133- feedback: dict
134- - 'correct': list[str] — 正确的节点,增强置信度
135- - 'wrong': list[str] — 错误的节点,降低置信度
136- - 'reward': float — 全局奖励信号
137+ 把反馈写回系统——通过信号队列。
138 """
139 effect = {'reinforced': [], 'weakened': [], 'reward': 0.0}
140
141- # 正确的节点:增强置信度(cat2=独立引用) + 势场
142- for node_id in feedback.get('correct', []):
143- if self.graph.has_node(node_id):
144- self.state.update_confidence(node_id, 2, amount=2.0)
145- self.state.phi[node_id] = (
146- self.state.phi.get(node_id, 0.0) + 0.5
147- )
148- effect['reinforced'].append(node_id)
149-
150- # 错误的节点:衰减势场 + 削弱置信度
151- for node_id in feedback.get('wrong', []):
152- if self.graph.has_node(node_id):
153- self.state.phi[node_id] = (
154- self.state.phi.get(node_id, 0.0) * 0.5
155- )
156- self.state.weaken_confidence(node_id, amount=3.0)
157- effect['weakened'].append(node_id)
158+ # 正确的节点——创建正向信号
159+ correct = feedback.get('correct', [])
160+ if correct:
161+ signal = PendingSignal(
162+ source="feedback",
163+ tokens=correct,
164+ strength=2.0,
165+ polarity=1,
166+ metadata={"type": "correct"},
167+ )
168+ self.state.pending_signals.append(signal)
169+ effect['reinforced'] = list(correct)
170+
171+ # 错误的节点——创建负向信号
172+ wrong = feedback.get('wrong', [])
173+ if wrong:
174+ signal = PendingSignal(
175+ source="feedback",
176+ tokens=wrong,
177+ strength=3.0,
178+ polarity=-1,
179+ metadata={"type": "wrong"},
180+ )
181+ self.state.pending_signals.append(signal)
182+ effect['weakened'] = list(wrong)
183
184- # 全局奖励
185+ # 全局奖励——对当前活跃区域
186 reward = feedback.get('reward', 0.0)
187 effect['reward'] = reward
188- if reward > 0:
189- # 正奖励强化当前激活区域——按已有最强分量方向增强
190- for node_id in self.state.active_region:
191- if node_id in self.state.confidence:
192- alphas = self.state.confidence[node_id]
193- best_cat = alphas.index(max(alphas))
194- self.state.update_confidence(node_id, best_cat, amount=reward)
195- else:
196- self.state.update_confidence(node_id, 0, amount=reward)
197- elif reward < 0:
198- # 负奖励衰减当前激活区域(势场+置信度)
199- for node_id in self.state.active_region:
200- self.state.phi[node_id] *= max(0.1, 1.0 + reward)
201- self.state.weaken_confidence(node_id, amount=abs(reward))
202+ if reward != 0 and self.state.active_region:
203+ signal = PendingSignal(
204+ source="feedback",
205+ tokens=list(self.state.active_region)[:10],
206+ strength=abs(reward),
207+ polarity=1 if reward > 0 else -1,
208+ metadata={"type": "reward", "reward": reward},
209+ )
210+ self.state.pending_signals.append(signal)
211
212 self.state.last_feedback_effect = effect
213
214@@ -261,16 +335,12 @@ class CIERuntime:
215 # 清理输出缓冲
216 self._output_buffer.clear()
217 self._last_output = None
218- self._feedback_pending = False
219
220 # 保留:phi, confidence, anchor_nodes, ability_cores,
221 # experience_hits, experience_regions, skill_belt_candidates
222
223 self.state.output_mode = 'minimal'
224
225- # ──────────────────────────────────────
226- # 内部:输出即输入回灌
227- # ──────────────────────────────────────
228
229 def _feedback_loop(self, last_output: dict):
230 """
+23,
-0
1@@ -8,6 +8,26 @@ J(u,v) = 边流(中速)— 技能/流动偏置
2 注意力池总量 100 点守恒。
3 """
4
5+
6+from dataclasses import dataclass, field as dc_field
7+from typing import Any as TypAny
8+
9+
10+@dataclass
11+class PendingSignal:
12+ """
13+ 统一信号对象(来自 Branch A)。
14+ 所有输入/反馈/回灌都先排队为 PendingSignal,在下一步 step 时消费。
15+ """
16+ source: str # "external" | "emit" | "feedback"
17+ tokens: list # 主 token 列表
18+ context_tokens: list = dc_field(default_factory=list)
19+ anchor_tokens: list = dc_field(default_factory=list)
20+ strength: float = 1.0 # 信号强度
21+ polarity: int = 1 # 1=正向, -1=负向
22+ metadata: dict = dc_field(default_factory=dict)
23+
24+
25 from collections import defaultdict
26 import math
27 import random
28@@ -113,6 +133,9 @@ class CIEState:
29 # ── 步计数 ──
30 self.step_count: int = 0
31
32+ # ── 信号队列(来自 Branch A) ──
33+ self.pending_signals: list = [] # List[PendingSignal]
34+
35 # ── 反馈效果 ──
36 self.last_feedback_effect: dict = {}
37