Spaces:
Sleeping
Sleeping
| """ | |
| ๋ฉํ์ธ์ง ์์ด์ ํธ (Metacognitive Agent) | |
| ์ด ์์ด์ ํธ๋ ๋ค์๊ณผ ๊ฐ์ ๋ฉํ์ธ์ง ์ ๋ต์ ์ฌ์ฉํฉ๋๋ค: | |
| 1. Planning (๊ณํ): ๋ต๋ณ ์ ๋ต ์๋ฆฝ | |
| 2. Monitoring (๊ฐ์): ๋ต๋ณ ๊ณผ์ ๋ชจ๋ํฐ๋ง | |
| 3. Evaluation (ํ๊ฐ): ๋ต๋ณ ํ์ง ํ๊ฐ | |
| 4. Revision (์์ ): ํ์์ ๋ต๋ณ ๊ฐ์ | |
| """ | |
| from typing import List, Dict, Optional | |
| from anthropic import Anthropic | |
| from loguru import logger | |
| import json | |
| class MetaCognitiveAgent: | |
| """๋ฉํ์ธ์ง ๋ฅ๋ ฅ์ ๊ฐ์ง AI ์์ด์ ํธ""" | |
| def __init__(self, api_key: str): | |
| """ | |
| Args: | |
| api_key: Anthropic API ํค | |
| """ | |
| self.client = Anthropic(api_key=api_key) | |
| self.thinking_history = [] | |
| self.model = "claude-3-5-sonnet-20241022" | |
| # ๋ฉํ์ธ์ง ํ๋กฌํํธ | |
| self.reflection_prompts = { | |
| "planning": """ | |
| ๋น์ ์ ๊ธ์ต/๊ฒฝ์ ๋ถ์ผ์ ์ ๋ฌธ๊ฐ์ ๋๋ค. ๋ค์ ์ง๋ฌธ์ ๋ตํ๊ธฐ ์ํ ์ ๋ต์ ์๋ฆฝํ์ธ์. | |
| ์ง๋ฌธ: {query} | |
| ๊ฒ์๋ ๊ด๋ จ ๋ฌธ์: | |
| {context} | |
| ๋ค์ ์ฌํญ์ ๊ณ ๋ คํ์ฌ ๋ต๋ณ ๊ณํ์ ์ธ์ฐ์ธ์: | |
| 1. ์ง๋ฌธ์ด ์๊ตฌํ๋ ํต์ฌ ์ ๋ณด๋ ๋ฌด์์ธ๊ฐ? | |
| 2. ์ ๊ณต๋ ๋ฌธ์๋ค์ด ์ง๋ฌธ์ ๋ตํ๊ธฐ์ ์ถฉ๋ถํ๊ฐ? | |
| 3. ์ด๋ค ์ ๋ณด๋ฅผ ์ฐ์ ์ ์ผ๋ก ์ฌ์ฉํด์ผ ํ๋๊ฐ? | |
| 4. ์ฃผ์ํด์ผ ํ ์ ์ด๋ ํ๊ณ๋ ๋ฌด์์ธ๊ฐ? | |
| ๊ณํ์ JSON ํ์์ผ๋ก ์์ฑํ์ธ์: | |
| {{ | |
| "key_information": "์ง๋ฌธ์ ํต์ฌ ์ ๋ณด", | |
| "context_adequacy": "๋ฌธ์์ ์ถฉ๋ถ์ฑ (์ถฉ๋ถ/๋ถ์กฑ/๋ถํ์ค)", | |
| "strategy": "๋ต๋ณ ์ ๋ต", | |
| "limitations": "์ฃผ์์ฌํญ ๋ฐ ํ๊ณ" | |
| }} | |
| """, | |
| "monitoring": """ | |
| ํ์ฌ ์์ฑ ์ค์ธ ๋ต๋ณ์ ๊ฒํ ํ์ธ์. | |
| ์ง๋ฌธ: {query} | |
| ํ์ฌ ๋ต๋ณ: {response} | |
| ๋ค์์ ํ์ธํ์ธ์: | |
| 1. ๋ต๋ณ์ด ์ง๋ฌธ์ ์ง์ ์ ์ผ๋ก ๋๋ตํ๊ณ ์๋๊ฐ? | |
| 2. ์ ๊ณต๋ ๋ฌธ์์ ์ ๋ณด๋ฅผ ์ ํํ ์ฌ์ฉํ๊ณ ์๋๊ฐ? | |
| 3. ์ถ๋ก ์ด ๋ ผ๋ฆฌ์ ์ผ๋ก ํ๋นํ๊ฐ? | |
| 4. Hallucination(๊ทผ๊ฑฐ ์๋ ์ ๋ณด)์ด ํฌํจ๋์ด ์์ง ์์๊ฐ? | |
| ํ๊ฐ๋ฅผ JSON ํ์์ผ๋ก ์์ฑํ์ธ์: | |
| {{ | |
| "relevance": "์ง๋ฌธ๊ณผ์ ๊ด๋ จ์ฑ (๋์/์ค๊ฐ/๋ฎ์)", | |
| "accuracy": "์ ํ์ฑ (๋์/์ค๊ฐ/๋ฎ์)", | |
| "logic": "๋ ผ๋ฆฌ์ฑ (ํ๋นํจ/๋ณดํต/๋ฌธ์ ์์)", | |
| "hallucination_risk": "Hallucination ์ํ๋ (๋ฎ์/์ค๊ฐ/๋์)", | |
| "issues": ["๋ฐ๊ฒฌ๋ ๋ฌธ์ ์ ๋ค"] | |
| }} | |
| """, | |
| "evaluation": """ | |
| ์ต์ข ๋ต๋ณ์ ํ๊ฐํ์ธ์. | |
| ์ง๋ฌธ: {query} | |
| ๋ต๋ณ: {response} | |
| ์ฌ์ฉ๋ ์ถ์ฒ: {sources} | |
| ๋ค์ ๊ธฐ์ค์ผ๋ก ํ๊ฐํ์ธ์: | |
| 1. ์์ ์ฑ: ์ง๋ฌธ์ ์์ ํ ๋ตํ๋๊ฐ? | |
| 2. ์ ํ์ฑ: ์ ๋ณด๊ฐ ์ ํํ๊ฐ? | |
| 3. ๋ช ํ์ฑ: ๋ต๋ณ์ด ๋ช ํํ๊ณ ์ดํดํ๊ธฐ ์ฌ์ด๊ฐ? | |
| 4. ์ ๋ขฐ์ฑ: ์ถ์ฒ๊ฐ ๋ช ํํ๊ณ ์ ๋ขฐํ ์ ์๋๊ฐ? | |
| ํ๊ฐ๋ฅผ JSON ํ์์ผ๋ก ์์ฑํ์ธ์: | |
| {{ | |
| "completeness": "์์ ์ฑ ์ ์ (1-10)", | |
| "accuracy": "์ ํ์ฑ ์ ์ (1-10)", | |
| "clarity": "๋ช ํ์ฑ ์ ์ (1-10)", | |
| "reliability": "์ ๋ขฐ์ฑ ์ ์ (1-10)", | |
| "overall_score": "์ ์ฒด ์ ์ (1-10)", | |
| "feedback": "๊ฐ์ ์ด ํ์ํ ๋ถ๋ถ" | |
| }} | |
| """, | |
| "revision": """ | |
| ๋ต๋ณ์ ๊ฐ์ ํ์ธ์. | |
| ์๋ณธ ๋ต๋ณ: {response} | |
| ํ๊ฐ ํผ๋๋ฐฑ: {feedback} | |
| ํผ๋๋ฐฑ์ ๋ฐํ์ผ๋ก ๋ต๋ณ์ ๊ฐ์ ํ์ธ์. ํนํ: | |
| 1. ๋ถ์ ํํ ์ ๋ณด ์์ | |
| 2. ๋ถ์์ ํ ๋ถ๋ถ ๋ณด์ | |
| 3. ๋ถ๋ช ํํ ํํ ๊ฐ์ | |
| 4. ๊ทผ๊ฑฐ ์๋ ์ฃผ์ฅ ์ ๊ฑฐ | |
| ๊ฐ์ ๋ ๋ต๋ณ๋ง ์ ๊ณตํ์ธ์. | |
| """ | |
| } | |
| async def think_and_reflect( | |
| self, | |
| query: str, | |
| context_documents: List[Dict], | |
| max_iterations: int = 2 | |
| ) -> Dict: | |
| """ | |
| ๋ฉํ์ธ์ง ๊ณผ์ ์ ํตํ ๋ต๋ณ ์์ฑ | |
| Args: | |
| query: ์ฌ์ฉ์ ์ง๋ฌธ | |
| context_documents: ๊ฒ์๋ ๊ด๋ จ ๋ฌธ์๋ค | |
| max_iterations: ์ต๋ ๊ฐ์ ๋ฐ๋ณต ํ์ | |
| Returns: | |
| ์ต์ข ๋ต๋ณ ๋ฐ ๋ฉํ์ธ์ง ๊ณผ์ ์ ๋ณด | |
| """ | |
| self.thinking_history = [] | |
| # ์ปจํ ์คํธ ํฌ๋งทํ | |
| context_text = self._format_context(context_documents) | |
| # 1๋จ๊ณ: ๊ณํ ์๋ฆฝ (Planning) | |
| logger.info("1๏ธโฃ Planning: ๋ต๋ณ ์ ๋ต ์๋ฆฝ ์ค...") | |
| plan = await self._plan(query, context_text) | |
| self.thinking_history.append({"step": "planning", "content": plan}) | |
| # 2๋จ๊ณ: ์ด๊ธฐ ์๋ต ์์ฑ | |
| logger.info("2๏ธโฃ Generating: ์ด๊ธฐ ๋ต๋ณ ์์ฑ ์ค...") | |
| initial_response = await self._generate_response(query, context_text, plan) | |
| self.thinking_history.append({"step": "initial_response", "content": initial_response}) | |
| # 3๋จ๊ณ: ๋ชจ๋ํฐ๋ง (Monitoring) | |
| logger.info("3๏ธโฃ Monitoring: ๋ต๋ณ ๊ฒํ ์ค...") | |
| monitoring_result = await self._monitor(query, initial_response) | |
| self.thinking_history.append({"step": "monitoring", "content": monitoring_result}) | |
| current_response = initial_response | |
| # 4๋จ๊ณ: ๋ฐ๋ณต์ ๊ฐ์ | |
| for iteration in range(max_iterations): | |
| # ํ๊ฐ (Evaluation) | |
| logger.info(f"4๏ธโฃ Evaluation [{iteration + 1}/{max_iterations}]: ๋ต๋ณ ํ๊ฐ ์ค...") | |
| evaluation = await self._evaluate( | |
| query, | |
| current_response, | |
| [doc.get('source_filename', 'unknown') for doc in context_documents] | |
| ) | |
| self.thinking_history.append({"step": f"evaluation_{iteration}", "content": evaluation}) | |
| # ํ๊ฐ ์ ์๊ฐ ์ถฉ๋ถํ ๋์ผ๋ฉด ์ข ๋ฃ | |
| try: | |
| eval_data = json.loads(evaluation) | |
| overall_score = float(eval_data.get('overall_score', 0)) | |
| if overall_score >= 8.0: | |
| logger.info(f"โ ์ถฉ๋ถํ ํ์ง ๋ฌ์ฑ (์ ์: {overall_score}/10)") | |
| break | |
| except: | |
| pass | |
| # ๊ฐ์ (Revision) | |
| logger.info(f"5๏ธโฃ Revision [{iteration + 1}/{max_iterations}]: ๋ต๋ณ ๊ฐ์ ์ค...") | |
| current_response = await self._revise(current_response, evaluation) | |
| self.thinking_history.append({"step": f"revision_{iteration}", "content": current_response}) | |
| return { | |
| "query": query, | |
| "final_response": current_response, | |
| "thinking_history": self.thinking_history, | |
| "context_documents": context_documents, | |
| "iterations": len([h for h in self.thinking_history if "revision" in h["step"]]) | |
| } | |
| async def _plan(self, query: str, context: str) -> str: | |
| """๊ณํ ์๋ฆฝ""" | |
| prompt = self.reflection_prompts["planning"].format( | |
| query=query, | |
| context=context | |
| ) | |
| message = self.client.messages.create( | |
| model=self.model, | |
| max_tokens=1024, | |
| messages=[{"role": "user", "content": prompt}] | |
| ) | |
| return message.content[0].text | |
| async def _generate_response(self, query: str, context: str, plan: str) -> str: | |
| """์ด๊ธฐ ์๋ต ์์ฑ""" | |
| prompt = f""" | |
| ๋น์ ์ ๊ธ์ต/๊ฒฝ์ ๋ถ์ผ์ ์ ๋ฌธ๊ฐ์ ๋๋ค. | |
| ๋ต๋ณ ๊ณํ: | |
| {plan} | |
| ์ง๋ฌธ: {query} | |
| ์ฐธ๊ณ ๋ฌธ์: | |
| {context} | |
| ์ ๊ณํ์ ๋ฐํ์ผ๋ก ์ง๋ฌธ์ ๋ต๋ณํ์ธ์. ๋ฐ๋์: | |
| 1. ์ ๊ณต๋ ๋ฌธ์์ ์ ๋ณด๋ง ์ฌ์ฉํ์ธ์ | |
| 2. ํ์คํ์ง ์์ ์ ๋ณด๋ ์ถ์ธกํ์ง ๋ง์ธ์ | |
| 3. ์ถ์ฒ๋ฅผ ๋ช ํํ ๋ฐํ์ธ์ | |
| 4. ํ๊ตญ์ด๋ก ๋ต๋ณํ์ธ์ | |
| """ | |
| message = self.client.messages.create( | |
| model=self.model, | |
| max_tokens=2048, | |
| messages=[{"role": "user", "content": prompt}] | |
| ) | |
| return message.content[0].text | |
| async def _monitor(self, query: str, response: str) -> str: | |
| """๋ต๋ณ ๋ชจ๋ํฐ๋ง""" | |
| prompt = self.reflection_prompts["monitoring"].format( | |
| query=query, | |
| response=response | |
| ) | |
| message = self.client.messages.create( | |
| model=self.model, | |
| max_tokens=1024, | |
| messages=[{"role": "user", "content": prompt}] | |
| ) | |
| return message.content[0].text | |
| async def _evaluate(self, query: str, response: str, sources: List[str]) -> str: | |
| """๋ต๋ณ ํ๊ฐ""" | |
| prompt = self.reflection_prompts["evaluation"].format( | |
| query=query, | |
| response=response, | |
| sources=", ".join(sources) | |
| ) | |
| message = self.client.messages.create( | |
| model=self.model, | |
| max_tokens=1024, | |
| messages=[{"role": "user", "content": prompt}] | |
| ) | |
| return message.content[0].text | |
| async def _revise(self, response: str, feedback: str) -> str: | |
| """๋ต๋ณ ๊ฐ์ """ | |
| prompt = self.reflection_prompts["revision"].format( | |
| response=response, | |
| feedback=feedback | |
| ) | |
| message = self.client.messages.create( | |
| model=self.model, | |
| max_tokens=2048, | |
| messages=[{"role": "user", "content": prompt}] | |
| ) | |
| return message.content[0].text | |
| def _format_context(self, documents: List[Dict]) -> str: | |
| """๋ฌธ์๋ค์ ์ปจํ ์คํธ ํ ์คํธ๋ก ํฌ๋งทํ """ | |
| formatted = [] | |
| for i, doc in enumerate(documents, 1): | |
| text = doc.get('text', doc.get('document', '')) | |
| metadata = doc.get('metadata', {}) | |
| source = metadata.get('source_filename', 'Unknown') | |
| formatted.append(f"[๋ฌธ์ {i}] {source}\n{text}\n") | |
| return "\n".join(formatted) | |