079project 1.0.0 → 2.0.0

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/main_Study.cjs CHANGED
@@ -79,6 +79,7 @@ async function batchAddPoints(graph, pointsArr, batchSize = 500) {
79
79
  await new Promise(resolve => setImmediate(resolve));
80
80
  }
81
81
  }
82
+ /*
82
83
  // 反触发机制
83
84
  async function antiTrigger(onContinue, onExit) {
84
85
  const PORT = global.config.emitExitport || 8641;
@@ -145,6 +146,7 @@ async function antiTrigger(onContinue, onExit) {
145
146
  }, 10000);
146
147
  }
147
148
  }
149
+ */
148
150
  function verifySystemConsistency(sourceRuntime, targetRuntime) {
149
151
  console.log('[VERIFY] 开始验证系统一致性...');
150
152
  console.log(`[VERIFY] 源词表大小: ${sourceRuntime.vocabManager.vocab.length}, 目标: ${targetRuntime.vocabManager.vocab.length}`);
@@ -163,12 +165,104 @@ const readline = require('readline');
163
165
 
164
166
  app.use(bodyParser.json());
165
167
  app.use(bodyParser.urlencoded({ extended: true }));
168
+ // ...existing code...
166
169
  app.use(express.static(path.join(__dirname, 'public')));
167
170
 
168
171
  // 持久化路径
169
172
  const SAVE_PATH = path.join(__dirname, 'runtime_data.json');
170
173
 
171
-
174
+ // 新增:会话管理器(以对话为尺度管理记忆)
175
+ class SessionManager {
176
+ constructor({ idleMs = 10 * 60 * 1000, maxSessions = 200 } = {}) {
177
+ this.idleMs = idleMs; // 会话空闲超时,自动切新会话
178
+ this.maxSessions = maxSessions; // 最近保留的会话数量上限(用于遗忘窗口)
179
+ this.sessions = new Map(); // sessionId -> { start, lastActivity, messageCount }
180
+ this.current = null;
181
+ }
182
+ now() { return Date.now(); }
183
+ _newId() { return `S${Date.now()}_${Math.floor(Math.random() * 1e6)}`; }
184
+
185
+ startNewSession(meta = {}) {
186
+ const id = this._newId();
187
+ const ts = this.now();
188
+ this.sessions.set(id, {
189
+ start: ts,
190
+ lastActivity: ts,
191
+ messageCount: 0,
192
+ ...meta
193
+ });
194
+ this.current = id;
195
+ this._truncateIfNeeded();
196
+ return id;
197
+ }
198
+ ensureActive() {
199
+ const ts = this.now();
200
+ if (!this.current || !this.sessions.has(this.current)) {
201
+ return this.startNewSession();
202
+ }
203
+ const s = this.sessions.get(this.current);
204
+ if (ts - s.lastActivity > this.idleMs) {
205
+ return this.startNewSession({ reason: 'idle-timeout' });
206
+ }
207
+ return this.current;
208
+ }
209
+ useSession(sessionId) {
210
+ if (!sessionId) return this.ensureActive();
211
+ if (!this.sessions.has(sessionId)) {
212
+ const ts = this.now();
213
+ this.sessions.set(sessionId, { start: ts, lastActivity: ts, messageCount: 0 });
214
+ }
215
+ this.current = sessionId;
216
+ return sessionId;
217
+ }
218
+ touch(sessionId = this.current) {
219
+ if (!sessionId) return;
220
+ const s = this.sessions.get(sessionId);
221
+ if (s) s.lastActivity = this.now();
222
+ }
223
+ incMessage(sessionId = this.current) {
224
+ if (!sessionId) return;
225
+ const s = this.sessions.get(sessionId);
226
+ if (s) {
227
+ s.messageCount = (s.messageCount || 0) + 1;
228
+ s.lastActivity = this.now();
229
+ }
230
+ }
231
+ getActiveSessionId() {
232
+ return this.ensureActive();
233
+ }
234
+ // 返回最近的会话ID(按 lastActivity 降序)
235
+ getRecentSessionIds(limit = this.maxSessions) {
236
+ const entries = Array.from(this.sessions.entries());
237
+ entries.sort((a, b) => (b[1].lastActivity || 0) - (a[1].lastActivity || 0));
238
+ return entries.slice(0, limit).map(([id]) => id);
239
+ }
240
+ _truncateIfNeeded() {
241
+ const ids = this.getRecentSessionIds(this.maxSessions);
242
+ const keep = new Set(ids);
243
+ for (const id of this.sessions.keys()) {
244
+ if (!keep.has(id)) this.sessions.delete(id);
245
+ }
246
+ }
247
+ export() {
248
+ return {
249
+ config: { idleMs: this.idleMs, maxSessions: this.maxSessions },
250
+ current: this.current,
251
+ sessions: Array.from(this.sessions.entries())
252
+ };
253
+ }
254
+ import(obj) {
255
+ if (!obj) return;
256
+ const { config, current, sessions } = obj;
257
+ if (config) {
258
+ this.idleMs = config.idleMs ?? this.idleMs;
259
+ this.maxSessions = config.maxSessions ?? this.maxSessions;
260
+ }
261
+ this.sessions = new Map(Array.isArray(sessions) ? sessions : []);
262
+ this.current = current || null;
263
+ }
264
+ }
265
+ // ...existing code...
172
266
 
173
267
 
174
268
  class SnapshotManager {
@@ -232,7 +326,12 @@ class SnapshotManager {
232
326
  wordGraph: Array.from(this.runtime.wordGraph.points.values()),
233
327
  kvm: Array.from(this.runtime.kvm.memory.entries()),
234
328
  vocab: this.runtime.vocabManager.vocab,
235
- wordAccessLog: Array.from(this.runtime.wordAccessLog ? this.runtime.wordAccessLog.entries() : [])
329
+ // 修正:序列化为 [word, [[sessionId,count], ...]]
330
+ wordAccessLog: Array.from(this.runtime.wordAccessLog.entries()).map(([w, per]) =>
331
+ [w, per instanceof Map ? Array.from(per.entries()) : (Array.isArray(per) ? [['legacy', per.length]] : [])]
332
+ ),
333
+ // 新增:保存会话状态
334
+ sessions: this.runtime.session.export()
236
335
  };
237
336
 
238
337
  // 写入临时文件,然后原子重命名以确保数据完整性
@@ -337,9 +436,25 @@ class SnapshotManager {
337
436
  // 恢复词访问日志
338
437
  console.log('[SNAPSHOT] 恢复词访问日志...');
339
438
  if (data.wordAccessLog) {
340
- this.runtime.wordAccessLog = new Map(data.wordAccessLog);
439
+ const restored = new Map();
440
+ for (const [word, per] of data.wordAccessLog) {
441
+ if (Array.isArray(per) && per.length > 0 && Array.isArray(per[0])) {
442
+ restored.set(word, new Map(per));
443
+ } else if (Array.isArray(per)) {
444
+ restored.set(word, new Map([['legacy', per.length]]));
445
+ } else {
446
+ restored.set(word, new Map());
447
+ }
448
+ }
449
+ this.runtime.wordAccessLog = restored;
450
+ }
451
+ // 恢复会话信息
452
+ if (data.sessions) {
453
+ this.runtime.session.import(data.sessions);
454
+ } else {
455
+ // 无会话信息时,创建一个遗留会话
456
+ this.runtime.session.startNewSession({ reason: 'snapshot-legacy' });
341
457
  }
342
-
343
458
  console.timeEnd('snapshotRestore');
344
459
  console.log(`[SNAPSHOT] 成功从快照恢复: ${snapshotId}`);
345
460
  return true;
@@ -802,15 +917,21 @@ class Runtime {
802
917
  this.transformer = null;
803
918
  this.vocabManager = global.vocabmanager;
804
919
  this.spider = new Spider();
920
+
921
+ // 新:以“会话”为尺度的访问日志与会话管理
922
+ this.session = new SessionManager({
923
+ idleMs: this.config.sessionIdleMs || 10 * 60 * 1000,
924
+ maxSessions: this.config.memoryRecentSessions || 200
925
+ });
926
+ // Map<word, Map<sessionId, count>>
805
927
  this.wordAccessLog = new Map();
928
+
806
929
  this.initWordGraph();
807
- this.forgetTimer = setInterval(() => this.forgetWords(), 350 * 1000); // 3. 判断是否合并到已有模因
808
- this.MAX_MEME_WORDS = 100; // 单个模因最大词数
809
- this.MIN_OVERLAP = 2; // 至少有2个词重叠才允许合并
810
- // Runtime类内新增
811
- this.activationStats = new Map(); // 记录激活关系
930
+ this.forgetTimer = setInterval(() => this.forgetWords(), 350 * 1000);
931
+ this.MAX_MEME_WORDS = 100;
932
+ this.MIN_OVERLAP = 2;
933
+ this.activationStats = new Map();
812
934
  this.isclone = false;
813
- // 添加系统资源监控
814
935
  this.systemLoad = {
815
936
  lastCpuUsage: process.cpuUsage(),
816
937
  lastCheckTime: Date.now(),
@@ -926,12 +1047,14 @@ class Runtime {
926
1047
  }
927
1048
 
928
1049
  // 记录词语点被访问
929
- logWordAccess(word) {
930
- const now = Date.now();
931
- if (!this.wordAccessLog.has(word)) {
932
- this.wordAccessLog.set(word, []);
1050
+ logWordAccess(word, sessionId) {
1051
+ const sid = sessionId || this.session.getActiveSessionId();
1052
+ let perSession = this.wordAccessLog.get(word);
1053
+ if (!perSession) {
1054
+ perSession = new Map();
1055
+ this.wordAccessLog.set(word, perSession);
933
1056
  }
934
- this.wordAccessLog.get(word).push(now);
1057
+ perSession.set(sid, (perSession.get(sid) || 0) + 1);
935
1058
  }
936
1059
  registerClone() {
937
1060
  Runtime.cloneRegistry.add(this);
@@ -939,62 +1062,65 @@ class Runtime {
939
1062
  // 不自动销毁
940
1063
  }
941
1064
 
942
- dispose() {
1065
+ dispose() {
943
1066
  this.graph.points.clear();
944
1067
  this.wordGraph.points.clear();
945
1068
  this.kvm.memory.clear();
946
1069
  if (this.wordAccessLog) this.wordAccessLog.clear();
947
1070
  if (this.forgetTimer) clearInterval(this.forgetTimer);
948
- // 其它属性也可清空
949
1071
  }
1072
+ // 将遗忘策略改为“最近N个会话窗口”
950
1073
  forgetWords() {
951
- const now = Date.now();
952
- const windowMs = 350 * 1000;
953
-
954
- // 只保留窗口内访问
955
- for (const [key, times] of this.wordAccessLog.entries()) {
956
- const recent = times.filter(t => now - t <= windowMs);
957
- this.wordAccessLog.set(key, recent);
958
- }
959
-
960
1074
  // 保护:收集所有被KVM引用的词
961
1075
  const protectedWords = new Set();
962
1076
  for (const [, words] of this.kvm.memory.entries()) {
963
- if (Array.isArray(words)) {
964
- for (const w of words) protectedWords.add(w);
965
- }
1077
+ if (Array.isArray(words)) for (const w of words) protectedWords.add(w);
966
1078
  }
967
1079
 
968
- // 若词表过小,直接跳过遗忘,避免崩塌
969
1080
  const vocabSize = this.vocabManager.vocab.length;
970
1081
  if (vocabSize < 1000) {
971
1082
  console.log('[FORGET] 词表过小,跳过本轮遗忘');
972
1083
  return;
973
1084
  }
974
1085
 
975
- // 仅对“存在于词图且不在保护集”的词做统计
1086
+ const recentSessions = this.session.getRecentSessionIds(this.config.memoryRecentSessions || 200);
1087
+ const recentSet = new Set(recentSessions);
1088
+
976
1089
  const stats = [];
977
- for (const [word, recent] of this.wordAccessLog.entries()) {
1090
+ for (const [word, perSession] of this.wordAccessLog.entries()) {
978
1091
  if (!this.wordGraph.points.has(word)) continue;
979
1092
  if (!this.vocabManager.word2idx.has(word)) continue;
980
1093
  if (protectedWords.has(word)) continue;
981
- stats.push({ word, count: recent.length });
1094
+
1095
+ // 统计最近会话窗口内的使用次数
1096
+ let count = 0;
1097
+ if (perSession instanceof Map) {
1098
+ for (const [sid, c] of perSession.entries()) {
1099
+ if (recentSet.has(sid)) count += c || 0;
1100
+ }
1101
+ } else if (Array.isArray(perSession)) {
1102
+ // 兼容旧格式(时间戳数组),视作一个遗留会话
1103
+ count = perSession.length;
1104
+ }
1105
+ stats.push({ word, count });
982
1106
  }
983
1107
  if (stats.length === 0) return;
984
1108
 
985
1109
  stats.sort((a, b) => a.count - b.count);
986
1110
 
987
- // 限制每轮上限,避免快速抽干
988
- const maxForgetRate = 0.001; // 改为每轮最多0.1%
1111
+ // 每轮最多遗忘 0.1%(更保守)
1112
+ const maxForgetRate = 0.001;
989
1113
  const n = Math.max(1, Math.floor(stats.length * maxForgetRate));
1114
+ const toForget = stats.slice(0, n).filter(s => s.count === 0).map(s => s.word);
1115
+
1116
+ if (toForget.length === 0) return;
990
1117
 
991
- const toForget = stats.slice(0, n).map(s => s.word);
992
1118
  for (const word of toForget) {
993
1119
  this.wordGraph.points.delete(word);
994
1120
  this.vocabManager.vocab = this.vocabManager.vocab.filter(w => w !== word);
995
1121
  this.vocabManager.updateMappings();
996
1122
  this.wordAccessLog.delete(word);
997
- console.log(`[FORGET] 淘汰词语点: ${word}`);
1123
+ console.log(`[FORGET] 淘汰词语点(无最近会话使用): ${word}`);
998
1124
 
999
1125
  // 同步清理所有模因节点的词表
1000
1126
  for (const [memeID, words] of this.kvm.memory.entries()) {
@@ -1010,9 +1136,6 @@ class Runtime {
1010
1136
  }
1011
1137
  }
1012
1138
  }
1013
-
1014
- // 不在这里调用 runMainLoop,避免循环内触发再次遗忘
1015
- // this.runMainLoop();
1016
1139
  }
1017
1140
  // 修改 initWordGraph 方法
1018
1141
  initWordGraph() {
@@ -2571,10 +2694,10 @@ class controller {
2571
2694
  }
2572
2695
  // 处理用户输入
2573
2696
  async handleInput(text) {
2697
+ const sid = this.runtime.session.ensureActive();
2698
+ this.runtime.session.incMessage(sid);
2574
2699
  const words = text.toLowerCase().split(' ').filter(w => w.length > 0);
2575
2700
  this.runtime.processInput(words, { addNewWords: false });
2576
- // 用模因网络参与推理
2577
- //console.log('[DEBUG] 当前所有模因节点:', this.runtime.kvm.memory);
2578
2701
  return await this.runtime.generateResponseWithMemes(words);
2579
2702
  }
2580
2703
  // 启动自主学习
@@ -2648,15 +2771,23 @@ let saveQueued = false;
2648
2771
 
2649
2772
  // 保存所有点、图、词表等到硬盘
2650
2773
  function saveAll(runtime) {
2774
+ // 规范化 wordAccessLog 为 [word, [[sessionId, count], ...]]
2775
+ const serializedWordAccess = Array.from(runtime.wordAccessLog.entries()).map(([w, per]) => {
2776
+ if (per instanceof Map) return [w, Array.from(per.entries())];
2777
+ if (Array.isArray(per)) return [w, [['legacy', per.length]]]; // 兼容旧格式
2778
+ return [w, []];
2779
+ });
2780
+
2651
2781
  // 只更新内存缓存
2652
2782
  latestRuntimeData = {
2653
2783
  memes: runtime.graph.getAllPoints(),
2654
2784
  wordGraph: Array.from(runtime.wordGraph.points.values()),
2655
2785
  kvm: Array.from(runtime.kvm.memory.entries()),
2656
2786
  vocab: runtime.vocabManager.vocab,
2657
- wordAccessLog: Array.from(runtime.wordAccessLog ? runtime.wordAccessLog.entries() : [])
2787
+ wordAccessLog: serializedWordAccess,
2788
+ // 新增:会话信息持久化
2789
+ sessions: runtime.session.export()
2658
2790
  };
2659
- // 标记有保存请求
2660
2791
  saveQueued = true;
2661
2792
  }
2662
2793
  // 定时真正写入硬盘,只保存最新的
@@ -2669,6 +2800,7 @@ setInterval(() => {
2669
2800
  }
2670
2801
  }, 10000); // 每10秒最多写盘一次
2671
2802
  // 从硬盘恢复
2803
+ // 从硬盘恢复
2672
2804
  function loadAll(runtime) {
2673
2805
  if (!fs.existsSync(SAVE_PATH)) return;
2674
2806
  const data = JSON.parse(fs.readFileSync(SAVE_PATH, 'utf-8'));
@@ -2678,19 +2810,34 @@ function loadAll(runtime) {
2678
2810
  runtime.wordGraph.addPoint(point.pointID, point.connect);
2679
2811
  }
2680
2812
  }
2681
- // 3. 修改 loadAll 中的数据恢复
2682
2813
  if (data.kvm) {
2683
2814
  for (const [k, v] of data.kvm) {
2684
2815
  runtime.kvm.set(k, Array.isArray(v) ? v : [String(v)]);
2685
- // 确保一定是数组
2686
2816
  }
2687
2817
  }
2688
2818
  if (data.vocab) {
2689
2819
  runtime.vocabManager.vocab = data.vocab;
2690
2820
  runtime.vocabManager.updateMappings();
2691
2821
  }
2822
+ // 恢复会话
2823
+ if (data.sessions) {
2824
+ runtime.session.import(data.sessions);
2825
+ }
2826
+ // 恢复词访问日志(新格式 Map<word, Map<sessionId, count>>)
2692
2827
  if (data.wordAccessLog && runtime.wordAccessLog) {
2693
- runtime.wordAccessLog = new Map(data.wordAccessLog);
2828
+ const restored = new Map();
2829
+ for (const [word, per] of data.wordAccessLog) {
2830
+ if (Array.isArray(per) && per.length > 0 && Array.isArray(per[0])) {
2831
+ // 新格式:[[sid, count], ...]
2832
+ restored.set(word, new Map(per));
2833
+ } else if (Array.isArray(per)) {
2834
+ // 旧格式的 timestamps 数组 -> 合并为 legacy 会话
2835
+ restored.set(word, new Map([['legacy', per.length]]));
2836
+ } else {
2837
+ restored.set(word, new Map());
2838
+ }
2839
+ }
2840
+ runtime.wordAccessLog = restored;
2694
2841
  }
2695
2842
  console.log(`[LOAD] 系统状态已从 ${SAVE_PATH} 恢复`);
2696
2843
  }
@@ -3041,17 +3188,28 @@ async function main() {
3041
3188
  ctrlA.runtime.memeBarrier.start();
3042
3189
  }, 1000 * 60 * 12);
3043
3190
  // API路由 - 只做学习,不返回结果
3044
- app.post('/api/chat', async (req, res) => {
3045
- try {
3046
- const { message } = req.body;
3047
- ctrlA.runtime.processInput(message.toLowerCase().split(' ').filter(w => w.length > 0));
3048
- ctrlA.runtime.updateAttentionLinks();
3049
- res.status(204).end(); // 不返回内容
3050
- } catch (error) {
3051
- res.status(500).json({ error: error.message });
3052
- console.error('Error in /api/chat:', error);
3053
- }
3054
- });
3191
+ app.post('/api/chat', async (req, res) => {
3192
+ try {
3193
+ const { message, sessionId } = req.body || {};
3194
+ // 支持从Header透传会话
3195
+ const headerSid = req.headers['x-session-id'];
3196
+ const sid = sessionId || headerSid || global.ctrlA.runtime.session.ensureActive();
3197
+
3198
+ // 使用/续接会话并计数
3199
+ global.ctrlA.runtime.session.useSession(sid);
3200
+ global.ctrlA.runtime.session.incMessage(sid);
3201
+
3202
+ const words = String(message || '').toLowerCase().split(/\s+/).filter(w => w.length > 0);
3203
+ global.ctrlA.runtime.processInput(words);
3204
+ global.ctrlA.runtime.updateAttentionLinks();
3205
+
3206
+ res.set('X-Session-Id', sid);
3207
+ res.status(204).end();
3208
+ } catch (error) {
3209
+ res.status(500).json({ error: error.message });
3210
+ console.error('Error in /api/chat:', error);
3211
+ }
3212
+ });
3055
3213
 
3056
3214
  app.get('/api/status', (req, res) => {
3057
3215
  res.json({ status: 'running', timestamp: new Date().toISOString() });
@@ -3208,16 +3366,7 @@ function applyModelParams(runtime) {
3208
3366
  }
3209
3367
  // 如果直接运行此文件,启动主函数
3210
3368
  if (require.main === module) {
3211
- /*antiTrigger(
3212
- () => main().catch(console.error), // onContinue
3213
- () => {
3214
- // onExit: 保存数据
3215
- try {
3216
- if (global.ctrl && global.ctrl.runtime) saveAll(global.ctrl.runtime);
3217
- } catch (e) { }
3218
- }
3219
- );
3220
- */
3369
+
3221
3370
  main().catch(console.error)
3222
3371
  }
3223
3372
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "079project",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "a GNN-GA BASED ai that might pass the turing test,which use little resources.its startpoint initialize it and you can start it as ```node mainStarter.cjs```",
5
5
  "keywords": [
6
6
  "ai",
package/todo-list.txt ADDED
@@ -0,0 +1,86 @@
1
+ GitHub Copilot
2
+
3
+ 下面把你提出的 v2.0 需求整理成清晰的 TODO-list(每项附带子任务、优先级、复杂度估算、首要改动点与下一步行动建议)。便于逐步实现与分支/PR 管理。
4
+
5
+ ------------------1) 记忆尺度:从“时间”切换为“对话”----------------
6
+ - 子任务:
7
+ - 定义“对话会话ID”与会话边界(消息计数或换话题检测)。
8
+ - 将 KVM/wordAccessLog/快照/遗忘策略改为按会话维度索引与过期。
9
+ - 修改 forgetWords、saveAll/loadAll 与 snapshot 逻辑以支持会话分片。
10
+ - 优先级:高;复杂度:中
11
+ - main_Study.cjs 中 KVM、forgetWords、SnapshotManager、save/load 函数。
12
+ - 下一步:设计会话ID格式并写出迁移方案(兼容老快照)。
13
+
14
+ 2) .copy -> 基于 hash 的差量 copy(递归分区哈希)
15
+ - 子任务:
16
+ - 定义对象哈希(图节点、连接、KVM 值、词表段)规则。
17
+ - 实现递归分区哈希算法(分层哈希,按子图/词块分区)。
18
+ - 实现差量 copy/patch 接口(只拷贝不同分区)。
19
+ - 优先级:高;复杂度:大
20
+ - 首要改动:实现新模块 lib/deltaCopy.js,替换 cloneSystem、runtimeToPlain/plainObjToRuntime。
21
+ - 下一步:写单元测试验证哈希一致性与补丁正确性。
22
+
23
+ 3) 增强轮换学习(减少用户等待)
24
+ - 子任务:
25
+ - 设计三副本轮换协议(leader/worker 与暂停/热替换流程)。
26
+ - 将 scheduleCrossLearning 改为更细粒度的 checkpoint/lock-free 切换(差量同步)。
27
+ - 添加短暂停机降级策略与快速回滚。
28
+ - 优先级:高;复杂度:中-大
29
+ - 首要改动:main_Study 中 scheduleCrossLearning、controller.updateRuntime、Redis 发布逻辑。
30
+ - 下一步:定义状态机与 API(swap、freeze、apply-delta)。
31
+
32
+ 4) 强化 anti-trigger 与日志系统(崩溃连锁触发定位) ---------------------
33
+ - 子任务:
34
+ - 完善 antiTrigger:崩溃链路检测、重试与安全退出钩子。
35
+ - 引入结构化日志(文件+rotating)与异常追踪(stack + context)。
36
+ - 在关键路径增加崩溃快照(错误发生时自动 dump 最小快照)。
37
+ - 优先级:高;复杂度:中
38
+ - 首要改动:antiTrigger 函数、setupExitHandler、SnapshotManager.createSnapshot、新增 logger 模块(winston 或 pino)。
39
+ - 下一步:定义日志格式与最小 crash dump 方案。
40
+
41
+ 5) 新增对抗学习网络(人机识别评分器)
42
+ - 子任务:
43
+ - 设计对抗模块接口:判别器(discriminator)输出拟人化评分与训练回路。
44
+ - 用现有 KVM/graph 生成“人类样本”与“机器样本”数据集。
45
+ - 将判别器输出作为主模型训练/奖励信号的一部分(强化学习回路)。
46
+ - 优先级:中;复杂度:大
47
+ - 首要改动:新增模块 lib/adversary.js + Runtime 中训练/评估接入点。
48
+ - 下一步:先实现轻量判别器(简单特征+小分类器)做 POC。
49
+
50
+ 6) 实现真正的爬虫模块(抓取+清洗)
51
+ - 子任务:
52
+ - 新建爬虫模块(支持并发、robots、速率限制、去重、Pipeline 清洗)。
53
+ - 集成 HTML 解析、正文提取、语言检测、去噪与词形归一化。
54
+ - 将抓取结果发送到 spider.fetchArticles 的存储/队列。
55
+ - 优先级:中;复杂度:中-大
56
+ - 首要改动:新增目录 crawler/(fetcher、parser、cleaner、storage)。修改 Spider 以支持外部数据源。
57
+ - 下一步:先实现单域抓取与清洗流水线 POC。
58
+
59
+ 7) 硬盘型数据库构型(部分图结构磁盘化、自动加载)
60
+ - 子任务:
61
+ - 研究 LMDB/LevelDB/rocksdb 方案,设计图分片策略(按节点度、热度、hash-range)。
62
+ - 实现图分片接口(swap-in/out)、接近边界时触发预加载侦测。
63
+ - 修改 GraphDB/KVM 支持异步加载与缓存回退策略。
64
+ - 优先级:高(随着图变大必须);复杂度:大
65
+ - 首要改动:KVM 类扩展、GraphDB 重构为内存+持久层混合(lib/storage-adapter.js)。
66
+ - 下一步:选定数据库(建议 LMDB 或 RocksDB),实现最小存储适配层。
67
+
68
+ 8) 探索硬件加速(FPGA / 模拟运算)
69
+ - 子任务:
70
+ - 梳理热点(哪些计算最耗时:信号扩散、多源比对、距离计算)。
71
+ - 制定可被加速的计算接口(向量化、批处理、FPGA-friendly 格式)。
72
+ - 建立 POC:把最小工作负载移到 GPU/FPGA 模拟(或借助 SIMD/Native addon)。
73
+ - 优先级:低(研究/POC);复杂度:非常大(外部依赖)
74
+ - 首要改动:抽象计算层(lib/computeAdapter),便于未来替换为硬件实现。
75
+ - 下一步:先做性能分析与热点剖析,确定优先加速模块。
76
+
77
+ 交付建议(短期优先级)
78
+ - 阶段 1(2–4 周):1、3、4(最小破坏性改造) + 日志模块 + 单元测试覆盖关键函数。
79
+ - 阶段 2(4–8 周):2(差量 copy 实现)+ 7(存储适配 POC)+ 6(爬虫基础)。
80
+ - 阶段 3(8–16 周):5(对抗学习)+ 8(硬件加速 POC)+ 全面整合与回归测试。
81
+
82
+ 我可以马上开始:
83
+ - A) 生成分解后的 issue 列表与每项具体 code-change patch(推荐先做阶段1)。
84
+ - B) 直接在工作区创建 logger 模块并改造 antiTrigger + setupExitHandler(优先级高)。
85
+
86
+ 请选择要我现在执行的下一步(A / B / 或 指定某个任务编号)。
File without changes
@@ -1,27 +0,0 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bin.* filter=lfs diff=lfs merge=lfs -text
5
- *.bz2 filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.model filter=lfs diff=lfs merge=lfs -text
12
- *.msgpack filter=lfs diff=lfs merge=lfs -text
13
- *.onnx filter=lfs diff=lfs merge=lfs -text
14
- *.ot filter=lfs diff=lfs merge=lfs -text
15
- *.parquet filter=lfs diff=lfs merge=lfs -text
16
- *.pb filter=lfs diff=lfs merge=lfs -text
17
- *.pt filter=lfs diff=lfs merge=lfs -text
18
- *.pth filter=lfs diff=lfs merge=lfs -text
19
- *.rar filter=lfs diff=lfs merge=lfs -text
20
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
21
- *.tar.* filter=lfs diff=lfs merge=lfs -text
22
- *.tflite filter=lfs diff=lfs merge=lfs -text
23
- *.tgz filter=lfs diff=lfs merge=lfs -text
24
- *.xz filter=lfs diff=lfs merge=lfs -text
25
- *.zip filter=lfs diff=lfs merge=lfs -text
26
- *.zstandard filter=lfs diff=lfs merge=lfs -text
27
- *tfevents* filter=lfs diff=lfs merge=lfs -text