elly99 commited on
Commit
d0d31ed
·
verified ·
1 Parent(s): 3be0567

Create reasoning/agent_metacognition.py

Browse files
Files changed (1) hide show
  1. src/reasoning/agent_metacognition.py +217 -0
src/reasoning/agent_metacognition.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # © 2025 Elena Marziali — Code released under Apache 2.0 license.
2
+ # See LICENSE in the repository for details.
3
+ # Removal of this copyright is prohibited.
4
+
5
+ # === metacognitive_cycle ===
6
+ # Executes an iterative cycle of evaluation and improvement of the generated response.
7
+ # Combines qualitative feedback and semantic coherence score to decide whether to reformulate.
8
+ # Useful for simulating reflective and adaptive behavior.
9
+
10
+ def generate_objective_from_input(user_input):
11
+ """
12
+ Generates a high-level operational objective based on the user's input.
13
+ Useful for AGI-style planning and decision-making.
14
+ """
15
+ prompt = f"""
16
+ You are an autonomous scientific agent. Based on the following input:
17
+ "{user_input}"
18
+
19
+ Define a clear and actionable objective that guides the agent's next steps.
20
+ """
21
+ try:
22
+ response = llm.invoke(prompt.strip())
23
+ return getattr(response, "content", str(response)).strip()
24
+ except Exception as e:
25
+ logging.error(f"Error generating objective: {e}")
26
+ return "Objective generation failed."
27
+
28
+
29
+ def metacognitive_cycle(question, level, max_iter=2):
30
+ response = llm.invoke(question)
31
+ response_text = extract_text_from_ai(response)
32
+
33
+ for i in range(max_iter):
34
+ feedback = auto_feedback_response(question, response_text, level)
35
+ score = evaluate_coherence(question, response_text)
36
+
37
+ print(f"\nIteration {i+1} – Coherence: {score:.3f}")
38
+ print("Feedback:", extract_text_from_ai(feedback))
39
+
40
+ if score < 0.7:
41
+ response_text = extract_text_from_ai(improve_response(question, response_text, level))
42
+ else:
43
+ break
44
+
45
+ return response_text
46
+
47
+ # Evaluate response with self-assessment and interactive improvement
48
+ # Evaluates the response and reformulates it if poorly constructed
49
+ def evaluate_responses_with_ai(question, generate_response_fn, n_variants=3, reformulation_threshold=0.6):
50
+ temperature_values = [0.7, 0.4, 0.9][:n_variants]
51
+ responses = [generate_response_fn(question, temperature=t) for t in temperature_values]
52
+
53
+ scores = [evaluate_coherence(question, r) for r in responses]
54
+ idx = scores.index(max(scores))
55
+ confidence = scores[idx]
56
+ best_response = responses[idx]
57
+
58
+ if confidence < reformulation_threshold:
59
+ new_question = reformulate_question(question)
60
+ return evaluate_responses_with_ai(new_question, generate_response_fn)
61
+
62
+ return {
63
+ "response": best_response,
64
+ "confidence": round(confidence, 3),
65
+ "note": generate_note(confidence)
66
+ }
67
+
68
+ def evaluate_responses_with_ai_simple(question, response, level="basic"):
69
+ """
70
+ Evaluates the quality of the generated response relative to the question.
71
+ Returns a dictionary with:
72
+ - semantic coherence score
73
+ - reason for weakness
74
+ - suggested reformulation
75
+ - reflection on reasoning
76
+ - flag for auto-improvement
77
+ """
78
+
79
+ evaluation_prompt = f"""
80
+ User question: "{question}"
81
+ Generated response: "{response}"
82
+ Required level: {level}
83
+
84
+ Evaluate the response in 5 points:
85
+ 1. Semantic coherence (0–1)
86
+ 2. Conceptual completeness
87
+ 3. Argumentative structure
88
+ 4. Adequacy to the required level
89
+ 5. Ability to stimulate new questions
90
+
91
+ If the response is weak:
92
+ - Explain the reason
93
+ - Suggest a reformulation
94
+ - Reflect on how the system reasoned
95
+
96
+ Return everything in structured format.
97
+ """
98
+
99
+ try:
100
+ ai_evaluation = llm.invoke(evaluation_prompt)
101
+ raw_output = getattr(ai_evaluation, "content", str(ai_evaluation))
102
+ except Exception as e:
103
+ print("Evaluation error:", e)
104
+ return {
105
+ "semantic_score": 0.0,
106
+ "weakness_reason": "System error",
107
+ "new_formulation": None,
108
+ "self_reflection": None,
109
+ "requires_improvement": True
110
+ }
111
+
112
+ # Simplified parsing functions (can be enhanced with regex or LLM)
113
+ def extract_score(text):
114
+ match = re.search(r"Semantic coherence\s*[:\-]?\s*(0\.\d+)", text)
115
+ return float(match.group(1)) if match else 0.0
116
+
117
+ def extract_reason(text):
118
+ match = re.search(r"Reason\s*[:\-]?\s*(.+)", text)
119
+ return match.group(1).strip() if match else "Reason not found."
120
+
121
+ def extract_reformulation(text):
122
+ match = re.search(r"Reformulation\s*[:\-]?\s*(.+)", text)
123
+ return match.group(1).strip() if match else None
124
+
125
+ def extract_reflection(text):
126
+ match = re.search(r"Reflection\s*[:\-]?\s*(.+)", text)
127
+ return match.group(1).strip() if match else None
128
+
129
+ # Actual parsing
130
+ score = extract_score(raw_output)
131
+ reason = extract_reason(raw_output)
132
+ reformulation = extract_reformulation(raw_output)
133
+ reflection = extract_reflection(raw_output)
134
+
135
+ return {
136
+ "response": response,
137
+ "semantic_score": score,
138
+ "weakness_reason": reason,
139
+ "new_formulation": reformulation,
140
+ "self_reflection": reflection,
141
+ "requires_improvement": score < 0.7
142
+ }
143
+
144
+ def generate_metacognitive_content(question, response, evaluation):
145
+ return f"""
146
+ [Question] {question}
147
+ [Response] {response}
148
+ [Coherence Score] {evaluation['semantic_score']}
149
+ [Weakness Reason] {evaluation['weakness_reason']}
150
+ [Suggested Reformulation] {evaluation['new_formulation']}
151
+ [Cognitive Reflection] {evaluation['self_reflection']}
152
+ [Needs Improvement] {evaluation['requires_improvement']}
153
+ """.strip()
154
+
155
+ def add_metacognitive_memory(question, response):
156
+ # Cognitive evaluation of the response
157
+ evaluation = evaluate_responses_with_ai(question, response)
158
+
159
+ # Generate textual content with all metacognitive data
160
+ textual_content = generate_metacognitive_content(question, response, evaluation)
161
+
162
+ # Generate semantic embedding from the full content
163
+ embedding = embedding_model.encode([textual_content])
164
+
165
+ # Add to FAISS index
166
+ index.add(np.array(embedding, dtype=np.float32))
167
+
168
+ # Save updated index
169
+ with open(INDEX_FILE, "wb") as f:
170
+ pickle.dump(index, f)
171
+
172
+ print("Metacognitive memory updated!")
173
+
174
+ def search_similar_reasoning(query, top_k=5):
175
+ """
176
+ Searches the FAISS metacognitive memory for reasoning most similar to the input query.
177
+ Returns a list of the most relevant textual contents.
178
+ """
179
+ # Encode the query
180
+ query_vector = embedding_model.encode([query])
181
+
182
+ # Search for top-K nearest
183
+ distances, indices = index.search(np.array(query_vector, dtype=np.float32), top_k)
184
+
185
+ results = []
186
+ for idx in indices[0]:
187
+ try:
188
+ with open("meta_diary.json", "r", encoding="utf-8") as f:
189
+ archive = json.load(f)
190
+ content = archive.get(str(idx))
191
+ if content:
192
+ results.append(content)
193
+ except Exception as e:
194
+ print(f"Memory retrieval error: {e}")
195
+
196
+ return results
197
+
198
+ def add_metacognition_to_response(response, evaluation):
199
+ reflection = evaluation.get("self_reflection", "")
200
+ note = evaluation.get("weakness_reason", "")
201
+ return f"{response.strip()}\n\n*Metacognitive note:* {note}\n*Agent's reflection:* {reflection}"
202
+
203
+ def auto_feedback(question, response, level):
204
+ return f"""Analyze the response in relation to the question: "{question}".
205
+ Evaluate the content according to the level '{level}' and suggest improvements.
206
+ """
207
+
208
+ # === Full flow example ===
209
+ async def scientific_creativity_flow(concept, subject, language="en", level="advanced"):
210
+ creative_hypothesis = simulate_scientific_creativity(concept, subject, language=language, level=level)
211
+ articles, _ = await search_multi_database(concept) # Retrieve existing scientific sources
212
+ novelty_evaluation = evaluate_hypothesis_novelty(creative_hypothesis, articles)
213
+
214
+ return {
215
+ "hypothesis": creative_hypothesis,
216
+ "novelty": novelty_evaluation
217
+ }