mark-improving-agent 2.2.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/README.md +335 -0
- package/VERSION +1 -0
- package/bin/cli.js +12 -0
- package/dist/agent/context.js +78 -0
- package/dist/agent/index.js +6 -0
- package/dist/agent/runtime.js +195 -0
- package/dist/agent/task-graph.js +209 -0
- package/dist/agent/types.js +1 -0
- package/dist/cli/index.js +206 -0
- package/dist/core/cognition/active-inference.js +296 -0
- package/dist/core/cognition/cognitive-architecture.js +263 -0
- package/dist/core/cognition/dual-process.js +102 -0
- package/dist/core/cognition/index.js +13 -0
- package/dist/core/cognition/learning-from-failure.js +184 -0
- package/dist/core/cognition/meta-agent.js +407 -0
- package/dist/core/cognition/metacognition.js +322 -0
- package/dist/core/cognition/react.js +177 -0
- package/dist/core/cognition/retrieval-anchor.js +99 -0
- package/dist/core/cognition/self-evolution.js +294 -0
- package/dist/core/cognition/self-verification.js +190 -0
- package/dist/core/cognition/thought-graph.js +495 -0
- package/dist/core/cognition/tool-augmented-llm.js +188 -0
- package/dist/core/cognition/tool-execution-verifier.js +204 -0
- package/dist/core/collaboration/agentic-loop.js +165 -0
- package/dist/core/collaboration/index.js +3 -0
- package/dist/core/collaboration/multi-agent-system.js +186 -0
- package/dist/core/collaboration/multi-agent.js +110 -0
- package/dist/core/consciousness/emotion-engine.js +101 -0
- package/dist/core/consciousness/flow-machine.js +121 -0
- package/dist/core/consciousness/index.js +4 -0
- package/dist/core/consciousness/personality.js +103 -0
- package/dist/core/consciousness/types.js +1 -0
- package/dist/core/emotional-protocol.js +54 -0
- package/dist/core/evolution/engine.js +194 -0
- package/dist/core/evolution/goal-engine.js +153 -0
- package/dist/core/evolution/index.js +6 -0
- package/dist/core/evolution/meta-learning.js +172 -0
- package/dist/core/evolution/reflection.js +158 -0
- package/dist/core/evolution/self-healer.js +139 -0
- package/dist/core/evolution/types.js +1 -0
- package/dist/core/healing-rl.js +266 -0
- package/dist/core/heartbeat.js +408 -0
- package/dist/core/identity/index.js +3 -0
- package/dist/core/identity/reflexion.js +165 -0
- package/dist/core/identity/self-model.js +274 -0
- package/dist/core/identity/self-verifier.js +158 -0
- package/dist/core/identity/types.js +12 -0
- package/dist/core/lesson-bank.js +301 -0
- package/dist/core/memory/adaptive-rag.js +440 -0
- package/dist/core/memory/archive-store.js +187 -0
- package/dist/core/memory/dream-consolidation.js +366 -0
- package/dist/core/memory/embedder.js +130 -0
- package/dist/core/memory/hopfield-network.js +128 -0
- package/dist/core/memory/index.js +9 -0
- package/dist/core/memory/knowledge-graph.js +151 -0
- package/dist/core/memory/spaced-repetition.js +113 -0
- package/dist/core/memory/store.js +404 -0
- package/dist/core/memory/types.js +1 -0
- package/dist/core/psychology/analysis.js +456 -0
- package/dist/core/psychology/index.js +1 -0
- package/dist/core/rollback-manager.js +191 -0
- package/dist/core/security/index.js +1 -0
- package/dist/core/security/privacy.js +132 -0
- package/dist/core/truth-teller.js +253 -0
- package/dist/core/truthfulness.js +99 -0
- package/dist/core/types.js +2 -0
- package/dist/event/bus.js +47 -0
- package/dist/index.js +8 -0
- package/dist/skills/dag.js +181 -0
- package/dist/skills/index.js +5 -0
- package/dist/skills/registry.js +40 -0
- package/dist/skills/types.js +1 -0
- package/dist/storage/archive.js +77 -0
- package/dist/storage/checkpoint.js +119 -0
- package/dist/storage/types.js +1 -0
- package/dist/utils/config.js +81 -0
- package/dist/utils/logger.js +49 -0
- package/dist/version.js +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-Evolution Engine - Survey of Self-Evolving AI Agents
|
|
3
|
+
*
|
|
4
|
+
* Paper: "Self-Evolving AI Agents: A Survey" (2025)
|
|
5
|
+
*
|
|
6
|
+
* Key concepts:
|
|
7
|
+
* - Environmental Feedback Loop: Agent → Environment → Feedback → Agent (update)
|
|
8
|
+
* - Self-improvement mechanisms: Self-taught reasoning, skill acquisition, knowledge update
|
|
9
|
+
* - Three paradigms: Reinforcement Learning, LLM self-training, Multi-agent collaboration
|
|
10
|
+
*
|
|
11
|
+
* Evolution modes:
|
|
12
|
+
* - Task-driven evolution: Improve performance on specific tasks
|
|
13
|
+
* - Capability-driven: Expand capabilities beyond current limits
|
|
14
|
+
* - Principled-driven: Align with human values and ethics
|
|
15
|
+
*
|
|
16
|
+
* Key mechanisms:
|
|
17
|
+
* - Experience sampling and storage
|
|
18
|
+
* - Skill graph for capability tracking
|
|
19
|
+
* - Self-model maintenance
|
|
20
|
+
* - Evolution policy updates
|
|
21
|
+
*/
|
|
22
|
+
import { randomUUID } from 'crypto';
|
|
23
|
+
const DEFAULT_POLICY = {
|
|
24
|
+
mode: 'task_driven',
|
|
25
|
+
improvementRate: 0.1,
|
|
26
|
+
explorationRate: 0.2,
|
|
27
|
+
capabilityDecay: 0.05,
|
|
28
|
+
experienceRetention: 0.8,
|
|
29
|
+
};
|
|
30
|
+
const CAPABILITY_DECAY_THRESHOLD_DAYS = 7;
|
|
31
|
+
const MIN_EXPERIENCES_FOR_EVOLUTION = 3;
|
|
32
|
+
const EVOLUTION_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour
|
|
33
|
+
export function createSelfEvolutionEngine() {
|
|
34
|
+
let state = {
|
|
35
|
+
experiences: [],
|
|
36
|
+
capabilities: new Map(),
|
|
37
|
+
skillGraph: new Map(),
|
|
38
|
+
selfModel: {
|
|
39
|
+
id: randomUUID(),
|
|
40
|
+
capabilities: new Map(),
|
|
41
|
+
strengths: [],
|
|
42
|
+
weaknesses: [],
|
|
43
|
+
growthEdges: [],
|
|
44
|
+
selfAccuracy: 0.8,
|
|
45
|
+
lastUpdated: Date.now(),
|
|
46
|
+
},
|
|
47
|
+
policy: { ...DEFAULT_POLICY },
|
|
48
|
+
evolutionCount: 0,
|
|
49
|
+
lastEvolution: null,
|
|
50
|
+
};
|
|
51
|
+
function assessSelfAccuracy() {
|
|
52
|
+
// Compare self-assessed capabilities with actual performance
|
|
53
|
+
if (state.experiences.length < 5)
|
|
54
|
+
return 0.8; // Default
|
|
55
|
+
let correctAssessments = 0;
|
|
56
|
+
let totalAssessments = 0;
|
|
57
|
+
for (const exp of state.experiences.slice(-20)) {
|
|
58
|
+
for (const capId of exp.capabilities) {
|
|
59
|
+
const cap = state.capabilities.get(capId);
|
|
60
|
+
if (!cap)
|
|
61
|
+
continue;
|
|
62
|
+
totalAssessments++;
|
|
63
|
+
// If success rate matches proficiency estimate
|
|
64
|
+
const expSuccess = exp.result === 'success' ? 1 : exp.result === 'partial' ? 0.5 : 0;
|
|
65
|
+
if (Math.abs(cap.proficiency - expSuccess) < 0.3) {
|
|
66
|
+
correctAssessments++;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return totalAssessments > 0 ? correctAssessments / totalAssessments : 0.8;
|
|
71
|
+
}
|
|
72
|
+
function updateSelfModel() {
|
|
73
|
+
const selfModel = state.selfModel;
|
|
74
|
+
selfModel.capabilities = new Map(state.capabilities);
|
|
75
|
+
selfModel.lastUpdated = Date.now();
|
|
76
|
+
// Update strengths (high proficiency capabilities)
|
|
77
|
+
selfModel.strengths = [];
|
|
78
|
+
for (const [id, cap] of state.capabilities) {
|
|
79
|
+
if (cap.proficiency > 0.8) {
|
|
80
|
+
selfModel.strengths.push(cap.name);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Update weaknesses (low proficiency capabilities)
|
|
84
|
+
selfModel.weaknesses = [];
|
|
85
|
+
for (const [id, cap] of state.capabilities) {
|
|
86
|
+
if (cap.proficiency < 0.4) {
|
|
87
|
+
selfModel.weaknesses.push(cap.name);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Update growth edges (medium proficiency - room for improvement)
|
|
91
|
+
selfModel.growthEdges = [];
|
|
92
|
+
for (const [id, cap] of state.capabilities) {
|
|
93
|
+
if (cap.proficiency >= 0.4 && cap.proficiency <= 0.7) {
|
|
94
|
+
selfModel.growthEdges.push(cap.name);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Update self-accuracy
|
|
98
|
+
selfModel.selfAccuracy = assessSelfAccuracy();
|
|
99
|
+
}
|
|
100
|
+
function registerCapability(capability) {
|
|
101
|
+
const cap = {
|
|
102
|
+
...capability,
|
|
103
|
+
id: randomUUID(),
|
|
104
|
+
improvementCount: 0,
|
|
105
|
+
};
|
|
106
|
+
state.capabilities.set(cap.id, cap);
|
|
107
|
+
// Add to skill graph
|
|
108
|
+
if (!state.skillGraph.has(cap.id)) {
|
|
109
|
+
state.skillGraph.set(cap.id, new Set());
|
|
110
|
+
}
|
|
111
|
+
updateSelfModel();
|
|
112
|
+
return cap;
|
|
113
|
+
}
|
|
114
|
+
function improveCapability(capabilityId, amount) {
|
|
115
|
+
const cap = state.capabilities.get(capabilityId);
|
|
116
|
+
if (!cap)
|
|
117
|
+
return;
|
|
118
|
+
cap.proficiency = Math.min(1, cap.proficiency + amount * state.policy.improvementRate);
|
|
119
|
+
cap.improvementCount++;
|
|
120
|
+
cap.lastUsed = Date.now();
|
|
121
|
+
updateSelfModel();
|
|
122
|
+
}
|
|
123
|
+
function decayCapabilities() {
|
|
124
|
+
const now = Date.now();
|
|
125
|
+
const decayThreshold = CAPABILITY_DECAY_THRESHOLD_DAYS * 24 * 60 * 60 * 1000;
|
|
126
|
+
for (const cap of state.capabilities.values()) {
|
|
127
|
+
const timeSinceUse = now - cap.lastUsed;
|
|
128
|
+
if (timeSinceUse > decayThreshold) {
|
|
129
|
+
cap.proficiency = Math.max(0, cap.proficiency - state.policy.capabilityDecay * (timeSinceUse / decayThreshold));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
updateSelfModel();
|
|
133
|
+
}
|
|
134
|
+
function getCapability(capabilityId) {
|
|
135
|
+
return state.capabilities.get(capabilityId);
|
|
136
|
+
}
|
|
137
|
+
function getAllCapabilities() {
|
|
138
|
+
return Array.from(state.capabilities.values());
|
|
139
|
+
}
|
|
140
|
+
function addExperience(experience) {
|
|
141
|
+
const exp = {
|
|
142
|
+
...experience,
|
|
143
|
+
id: randomUUID(),
|
|
144
|
+
};
|
|
145
|
+
state.experiences.push(exp);
|
|
146
|
+
// Keep only recent experiences based on retention policy
|
|
147
|
+
const maxExperiences = Math.floor(100 * state.policy.experienceRetention);
|
|
148
|
+
if (state.experiences.length > maxExperiences) {
|
|
149
|
+
state.experiences = state.experiences.slice(-maxExperiences);
|
|
150
|
+
}
|
|
151
|
+
return exp;
|
|
152
|
+
}
|
|
153
|
+
function getRecentExperiences(limit = 10) {
|
|
154
|
+
return state.experiences.slice(-limit);
|
|
155
|
+
}
|
|
156
|
+
function extractLessons() {
|
|
157
|
+
const lessons = [];
|
|
158
|
+
// Analyze recent failures for patterns
|
|
159
|
+
const recentFailures = state.experiences.filter(e => e.result === 'failure').slice(-5);
|
|
160
|
+
for (const failure of recentFailures) {
|
|
161
|
+
if (failure.lessons.length > 0) {
|
|
162
|
+
lessons.push(...failure.lessons);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Analyze partial successes for improvements
|
|
166
|
+
const partialSuccesses = state.experiences.filter(e => e.result === 'partial').slice(-5);
|
|
167
|
+
for (const partial of partialSuccesses) {
|
|
168
|
+
if (partial.feedback) {
|
|
169
|
+
lessons.push(`Partial success feedback: ${partial.feedback}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return [...new Set(lessons)];
|
|
173
|
+
}
|
|
174
|
+
function shouldEvolve() {
|
|
175
|
+
const now = Date.now();
|
|
176
|
+
// Check cooldown
|
|
177
|
+
if (state.lastEvolution && now - state.lastEvolution < EVOLUTION_COOLDOWN_MS) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
// Need minimum experiences
|
|
181
|
+
if (state.experiences.length < MIN_EXPERIENCES_FOR_EVOLUTION) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
// Check if recent experiences show performance changes
|
|
185
|
+
const recentExps = getRecentExperiences(5);
|
|
186
|
+
const hasFailures = recentExps.some(e => e.result === 'failure');
|
|
187
|
+
const hasImprovements = recentExps.some(e => e.result === 'success');
|
|
188
|
+
return hasFailures || hasImprovements;
|
|
189
|
+
}
|
|
190
|
+
function evolve(experience) {
|
|
191
|
+
// First add the experience
|
|
192
|
+
addExperience(experience);
|
|
193
|
+
const improvements = [];
|
|
194
|
+
const newCapabilities = [];
|
|
195
|
+
const droppedCapabilities = [];
|
|
196
|
+
// Improve capabilities used in successful experiences
|
|
197
|
+
if (experience.result === 'success') {
|
|
198
|
+
for (const capId of experience.capabilities) {
|
|
199
|
+
improveCapability(capId, 0.1);
|
|
200
|
+
improvements.push(`Improved capability used in success`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Decay capabilities not used
|
|
204
|
+
decayCapabilities();
|
|
205
|
+
// Check for capabilities that dropped below threshold
|
|
206
|
+
for (const [id, cap] of state.capabilities) {
|
|
207
|
+
if (cap.proficiency < 0.1) {
|
|
208
|
+
droppedCapabilities.push(cap.name);
|
|
209
|
+
state.capabilities.delete(id);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Extract and store lessons
|
|
213
|
+
const lessons = experience.lessons;
|
|
214
|
+
if (lessons.length > 0) {
|
|
215
|
+
improvements.push(...lessons);
|
|
216
|
+
}
|
|
217
|
+
// Update self-model
|
|
218
|
+
updateSelfModel();
|
|
219
|
+
// Update state
|
|
220
|
+
state.evolutionCount++;
|
|
221
|
+
state.lastEvolution = Date.now();
|
|
222
|
+
return {
|
|
223
|
+
evolved: true,
|
|
224
|
+
improvements,
|
|
225
|
+
newCapabilities,
|
|
226
|
+
droppedCapabilities,
|
|
227
|
+
selfModelUpdated: true,
|
|
228
|
+
evolutionMode: state.policy.mode,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function getSelfModel() {
|
|
232
|
+
return { ...state.selfModel };
|
|
233
|
+
}
|
|
234
|
+
function getPolicy() {
|
|
235
|
+
return { ...state.policy };
|
|
236
|
+
}
|
|
237
|
+
function updatePolicy(policy) {
|
|
238
|
+
state.policy = { ...state.policy, ...policy };
|
|
239
|
+
}
|
|
240
|
+
function addSkillEdge(skillA, skillB) {
|
|
241
|
+
if (!state.skillGraph.has(skillA)) {
|
|
242
|
+
state.skillGraph.set(skillA, new Set());
|
|
243
|
+
}
|
|
244
|
+
if (!state.skillGraph.has(skillB)) {
|
|
245
|
+
state.skillGraph.set(skillB, new Set());
|
|
246
|
+
}
|
|
247
|
+
state.skillGraph.get(skillA).add(skillB);
|
|
248
|
+
state.skillGraph.get(skillB).add(skillA);
|
|
249
|
+
}
|
|
250
|
+
function getSkillGraph() {
|
|
251
|
+
const nodes = [];
|
|
252
|
+
const edges = [];
|
|
253
|
+
for (const [skillA, related] of state.skillGraph) {
|
|
254
|
+
nodes.push(skillA);
|
|
255
|
+
for (const skillB of related) {
|
|
256
|
+
edges.push([skillA, skillB]);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { nodes, edges };
|
|
260
|
+
}
|
|
261
|
+
function getStats() {
|
|
262
|
+
const capabilities = Array.from(state.capabilities.values());
|
|
263
|
+
const avgProficiency = capabilities.length > 0
|
|
264
|
+
? capabilities.reduce((sum, c) => sum + c.proficiency, 0) / capabilities.length
|
|
265
|
+
: 0;
|
|
266
|
+
return {
|
|
267
|
+
totalExperiences: state.experiences.length,
|
|
268
|
+
totalCapabilities: capabilities.length,
|
|
269
|
+
avgProficiency,
|
|
270
|
+
selfAccuracy: state.selfModel.selfAccuracy,
|
|
271
|
+
evolutionCount: state.evolutionCount,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
evolve,
|
|
276
|
+
shouldEvolve,
|
|
277
|
+
registerCapability,
|
|
278
|
+
improveCapability,
|
|
279
|
+
decayCapabilities,
|
|
280
|
+
getCapability,
|
|
281
|
+
getAllCapabilities,
|
|
282
|
+
getSelfModel,
|
|
283
|
+
updateSelfModel,
|
|
284
|
+
assessSelfAccuracy,
|
|
285
|
+
addExperience,
|
|
286
|
+
getRecentExperiences,
|
|
287
|
+
extractLessons,
|
|
288
|
+
getPolicy,
|
|
289
|
+
updatePolicy,
|
|
290
|
+
addSkillEdge,
|
|
291
|
+
getSkillGraph,
|
|
292
|
+
getStats,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-Verification - Reasoning Chain Verification
|
|
3
|
+
*
|
|
4
|
+
* Paper: "Why think step-by-step? Understanding Chain-of-Thought in LLMs"
|
|
5
|
+
* Key insight: CoT is NOT emergent - it comes from training process
|
|
6
|
+
*
|
|
7
|
+
* Key mechanisms:
|
|
8
|
+
* - Node-level verification: verify each intermediate step
|
|
9
|
+
* - Answer verification: verify final answer
|
|
10
|
+
* - Consistency checks: ensure logical flow
|
|
11
|
+
* - Self-correction: fix errors before final output
|
|
12
|
+
*/
|
|
13
|
+
export function createSelfVerificationEngine() {
|
|
14
|
+
let totalVerifications = 0;
|
|
15
|
+
let corrections = 0;
|
|
16
|
+
function verify(reasoningChain) {
|
|
17
|
+
totalVerifications++;
|
|
18
|
+
const verifiedSteps = [];
|
|
19
|
+
let corrections = 0;
|
|
20
|
+
for (const step of reasoningChain) {
|
|
21
|
+
const node = verifyStep(step, reasoningChain.slice(0, -1));
|
|
22
|
+
verifiedSteps.push(node);
|
|
23
|
+
if (!node.isValid) {
|
|
24
|
+
corrections++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const validSteps = verifiedSteps.filter(s => s.isValid);
|
|
28
|
+
const overallConfidence = validSteps.length > 0
|
|
29
|
+
? validSteps.reduce((sum, s) => sum + s.confidence, 0) / verifiedSteps.length
|
|
30
|
+
: 0;
|
|
31
|
+
return {
|
|
32
|
+
id: `chain-${Date.now()}`,
|
|
33
|
+
steps: verifiedSteps,
|
|
34
|
+
isValid: validSteps.length === verifiedSteps.length,
|
|
35
|
+
overallConfidence,
|
|
36
|
+
corrections,
|
|
37
|
+
timestamp: Date.now(),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function verifyStep(step, context) {
|
|
41
|
+
const checks = [];
|
|
42
|
+
// Check 1: Logic consistency
|
|
43
|
+
const logicCheck = checkLogic(step, context);
|
|
44
|
+
checks.push(logicCheck);
|
|
45
|
+
// Check 2: Factual accuracy
|
|
46
|
+
const factCheck = checkFacts(step);
|
|
47
|
+
checks.push(factCheck);
|
|
48
|
+
// Check 3: Arithmetic (if applicable)
|
|
49
|
+
const mathCheck = checkArithmetic(step);
|
|
50
|
+
checks.push(mathCheck);
|
|
51
|
+
// Check 4: Coherence with previous steps
|
|
52
|
+
const coherenceCheck = checkCoherence(step, context);
|
|
53
|
+
checks.push(coherenceCheck);
|
|
54
|
+
const passedChecks = checks.filter(c => c.passed).length;
|
|
55
|
+
const confidence = passedChecks / checks.length;
|
|
56
|
+
return {
|
|
57
|
+
id: `node-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
58
|
+
step,
|
|
59
|
+
isValid: passedChecks >= checks.length * 0.75, // Need 75% to pass
|
|
60
|
+
confidence,
|
|
61
|
+
checks,
|
|
62
|
+
timestamp: Date.now(),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function checkLogic(step, context) {
|
|
66
|
+
// Check for logical fallacies
|
|
67
|
+
const fallacies = [
|
|
68
|
+
{ pattern: /因为.*所以.*但.*没有/g, name: 'missing_premise' },
|
|
69
|
+
{ pattern: /如果.*那么.*但是/g, name: 'contradiction' },
|
|
70
|
+
{ pattern: /所有.*都是.*有些不是/g, name: 'overgeneralization' },
|
|
71
|
+
];
|
|
72
|
+
for (const fallacy of fallacies) {
|
|
73
|
+
if (fallacy.pattern.test(step)) {
|
|
74
|
+
return {
|
|
75
|
+
type: 'logic',
|
|
76
|
+
passed: false,
|
|
77
|
+
details: `Logical fallacy detected: ${fallacy.name}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
type: 'logic',
|
|
83
|
+
passed: true,
|
|
84
|
+
details: 'No logical fallacies detected',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function checkFacts(step) {
|
|
88
|
+
// Check for claims that need verification
|
|
89
|
+
const claimIndicators = ['确定', '肯定', '一定', '所有', '每个'];
|
|
90
|
+
const hasClaim = claimIndicators.some(ind => step.includes(ind));
|
|
91
|
+
if (hasClaim) {
|
|
92
|
+
const hasEvidence = step.includes('因为') || step.includes('根据') || step.includes('数据');
|
|
93
|
+
return {
|
|
94
|
+
type: 'fact',
|
|
95
|
+
passed: hasEvidence,
|
|
96
|
+
details: hasEvidence ? 'Claim has supporting evidence' : 'Claim without evidence',
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return { type: 'fact', passed: true, details: 'No unverified claims' };
|
|
100
|
+
}
|
|
101
|
+
function checkArithmetic(step) {
|
|
102
|
+
// Simple arithmetic check
|
|
103
|
+
const mathPattern = /\d+\s*[+\-*/=]\s*\d+/g;
|
|
104
|
+
const matches = step.match(mathPattern);
|
|
105
|
+
if (matches && matches.length > 0) {
|
|
106
|
+
// For now, just check format is valid
|
|
107
|
+
return {
|
|
108
|
+
type: 'arithmetic',
|
|
109
|
+
passed: true,
|
|
110
|
+
details: `${matches.length} arithmetic expression(s) found`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return { type: 'arithmetic', passed: true, details: 'No arithmetic to verify' };
|
|
114
|
+
}
|
|
115
|
+
function checkCoherence(step, context) {
|
|
116
|
+
if (!context || context.length === 0) {
|
|
117
|
+
return { type: 'coherence', passed: true, details: 'First step, no context to check' };
|
|
118
|
+
}
|
|
119
|
+
// Check if step contradicts previous steps
|
|
120
|
+
const contradictionIndicators = ['但是', '然而', '不过', '可是'];
|
|
121
|
+
const hasContradiction = contradictionIndicators.some(ind => step.includes(ind));
|
|
122
|
+
if (hasContradiction) {
|
|
123
|
+
// Check if contradiction is intentional (rebuttal) or error
|
|
124
|
+
const lastStep = context[context.length - 1];
|
|
125
|
+
const keywords = ['虽然', '尽管', '即使'];
|
|
126
|
+
const isIntentional = keywords.some(k => step.includes(k));
|
|
127
|
+
return {
|
|
128
|
+
type: 'coherence',
|
|
129
|
+
passed: isIntentional,
|
|
130
|
+
details: isIntentional ? 'Intentional rebuttal' : 'Possible contradiction',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return { type: 'coherence', passed: true, details: 'Coherent with context' };
|
|
134
|
+
}
|
|
135
|
+
function checkConsistency(steps) {
|
|
136
|
+
const issues = [];
|
|
137
|
+
for (let i = 0; i < steps.length - 1; i++) {
|
|
138
|
+
const current = steps[i];
|
|
139
|
+
const next = steps[i + 1];
|
|
140
|
+
// Check if next step contradicts current
|
|
141
|
+
if ((current.includes('是') && next.includes('不是')) ||
|
|
142
|
+
(current.includes('有') && next.includes('没有'))) {
|
|
143
|
+
issues.push(`Potential contradiction between step ${i + 1} and ${i + 2}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
consistent: issues.length === 0,
|
|
148
|
+
issues,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function selfCorrect(chain) {
|
|
152
|
+
const correctedSteps = [];
|
|
153
|
+
for (const node of chain.steps) {
|
|
154
|
+
if (!node.isValid) {
|
|
155
|
+
corrections++;
|
|
156
|
+
// Add correction step
|
|
157
|
+
const correction = {
|
|
158
|
+
id: `correct-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
159
|
+
step: `[Self-correction] Previous step failed: ${node.step}`,
|
|
160
|
+
isValid: true,
|
|
161
|
+
confidence: 0.9,
|
|
162
|
+
checks: [{ type: 'logic', passed: true, details: 'Correction verified' }],
|
|
163
|
+
timestamp: Date.now(),
|
|
164
|
+
};
|
|
165
|
+
correctedSteps.push(correction);
|
|
166
|
+
}
|
|
167
|
+
correctedSteps.push(node);
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
...chain,
|
|
171
|
+
steps: correctedSteps,
|
|
172
|
+
corrections: chain.corrections + correctedSteps.filter(s => s.step.startsWith('[Self-correction]')).length,
|
|
173
|
+
overallConfidence: chain.steps.filter(s => s.isValid).length / correctedSteps.length,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function getStats() {
|
|
177
|
+
return {
|
|
178
|
+
totalVerifications,
|
|
179
|
+
corrections,
|
|
180
|
+
avgConfidence: totalVerifications > 0 ? 0.85 : 0,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
verify,
|
|
185
|
+
verifyStep,
|
|
186
|
+
checkConsistency,
|
|
187
|
+
selfCorrect,
|
|
188
|
+
getStats,
|
|
189
|
+
};
|
|
190
|
+
}
|