{"product_id":"evaluator-optimizer-tự-cải-thiện-output-với-feedback-loop","title":"Evaluator-Optimizer — Tự cải thiện output với feedback loop","description":"\n\u003cp\u003eTrong quá trình viết lách, lập trình hay phân tích, con người thường làm theo vòng lặp: tạo ra thứ gì đó, xem lại, cải thiện, xem lại lần nữa. \u003cstrong\u003eEvaluator-Optimizer pattern\u003c\/strong\u003e mang chính vòng lặp tự nhiên này vào AI — tạo ra hệ thống tự cải thiện mà không cần can thiệp thủ công.\u003c\/p\u003e\n\n\u003ch2\u003eKiến trúc Evaluator-Optimizer\u003c\/h2\u003e\n\n\u003cp\u003ePattern này gồm hai thành phần chính hoạt động trong vòng lặp:\u003c\/p\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eGenerator\u003c\/strong\u003e — Tạo output ban đầu hoặc cải thiện theo feedback\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eEvaluator\u003c\/strong\u003e — Đánh giá output theo tiêu chí cụ thể, cung cấp actionable feedback\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eVòng lặp tiếp tục cho đến khi Evaluator chấp nhận output (đủ tốt) hoặc đến max iterations.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\nimport json\n\nclient = anthropic.Anthropic()\n\nclass EvaluatorOptimizer:\n    def __init__(self, task_description: str, evaluation_criteria: list[str],\n                 max_iterations: int = 4, quality_threshold: int = 8):\n        self.task = task_description\n        self.criteria = evaluation_criteria\n        self.max_iterations = max_iterations\n        self.threshold = quality_threshold\n        self.history = []\n\n    def run(self, initial_input: str = None) -\u0026gt; dict:\n        current_output = None\n        feedback_history = []\n\n        for iteration in range(self.max_iterations):\n            print(f\"\n--- Iteration {iteration + 1}\/{self.max_iterations} ---\")\n\n            # Generate\n            current_output = self._generate(\n                initial_input or self.task,\n                current_output,\n                feedback_history\n            )\n            print(f\"Generated ({len(current_output)} chars)\")\n\n            # Evaluate\n            eval_result = self._evaluate(current_output)\n            score = eval_result[\"score\"]\n            feedback = eval_result[\"feedback\"]\n\n            print(f\"Score: {score}\/10\")\n            print(f\"Feedback: {feedback[:100]}...\")\n\n            self.history.append({\n                \"iteration\": iteration + 1,\n                \"output\": current_output,\n                \"score\": score,\n                \"feedback\": feedback\n            })\n\n            if score \u0026gt;= self.threshold:\n                print(f\"Quality threshold {self.threshold} reached!\")\n                return {\n                    \"output\": current_output,\n                    \"final_score\": score,\n                    \"iterations_used\": iteration + 1,\n                    \"approved\": True,\n                    \"history\": self.history\n                }\n\n            feedback_history.append(f\"Round {iteration+1} (Score {score}\/10): {feedback}\")\n\n        return {\n            \"output\": current_output,\n            \"final_score\": eval_result[\"score\"],\n            \"iterations_used\": self.max_iterations,\n            \"approved\": False,\n            \"history\": self.history\n        }\n\n    def _generate(self, task: str, previous_output: str, feedback_history: list) -\u0026gt; str:\n        if not previous_output:\n            prompt = f\"Complete this task:\n\n{task}\"\n        else:\n            feedback_text = \"\n\".join(feedback_history)\n            prompt = f\"\"\"Task: {task}\n\nYour previous attempt:\n{previous_output}\n\nFeedback from evaluator (most recent last):\n{feedback_text}\n\nRewrite the output addressing ALL feedback points. Be specific about what you improved.\"\"\"\n\n        response = client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=3000,\n            messages=[{\"role\": \"user\", \"content\": prompt}]\n        )\n        return response.content[0].text\n\n    def _evaluate(self, output: str) -\u0026gt; dict:\n        criteria_text = \"\n\".join([f\"- {c}\" for c in self.criteria])\n\n        eval_prompt = f\"\"\"Evaluate this output against the criteria below.\n\nOutput to evaluate:\n{output}\n\nEvaluation criteria:\n{criteria_text}\n\nRespond in JSON format:\n{{\n  \"score\": [1-10 integer],\n  \"criteria_scores\": {{\"criterion\": score}},\n  \"strengths\": [\"list of what's good\"],\n  \"improvements\": [\"specific actionable improvements needed\"],\n  \"feedback\": \"concise summary for the generator\"\n}}\"\"\"\n\n        response = client.messages.create(\n            model=\"claude-haiku-4-5\",\n            max_tokens=1000,\n            messages=[{\"role\": \"user\", \"content\": eval_prompt}]\n        )\n\n        try:\n            text = response.content[0].text\n            # Extract JSON\n            start = text.find('{')\n            end = text.rfind('}') + 1\n            result = json.loads(text[start:end])\n            return result\n        except Exception:\n            return {\"score\": 5, \"feedback\": response.content[0].text}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eVí dụ 1: Tối ưu hóa nội dung Marketing\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Viết product description đạt chất lượng cao\noptimizer = EvaluatorOptimizer(\n    task_description=\"\"\"Write a product description for:\nProduct: Claude API Professional Plan\nTarget audience: Vietnamese tech startup CTOs\nGoal: Drive trial sign-ups\"\"\",\n\n    evaluation_criteria=[\n        \"Clear value proposition in first sentence\",\n        \"Addresses specific pain points of Vietnamese startups\",\n        \"Includes concrete numbers or metrics\",\n        \"Has strong call-to-action\",\n        \"Tone is professional but approachable\",\n        \"Length: 150-200 words\",\n        \"Mentions at least 3 specific features\",\n    ],\n    max_iterations=4,\n    quality_threshold=8\n)\n\nresult = optimizer.run()\n\nprint(f\"\nFinal output (score: {result['final_score']}\/10):\")\nprint(result['output'])\nprint(f\"\nIterations used: {result['iterations_used']}\")\nprint(f\"Approved: {result['approved']}\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eVí dụ 2: Code Review Loop\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eclass CodeOptimizer(EvaluatorOptimizer):\n    \"\"\"Chuyên biệt cho code generation + review\"\"\"\n\n    def __init__(self, language: str, task: str):\n        super().__init__(\n            task_description=task,\n            evaluation_criteria=[\n                f\"Code is valid {language} syntax\",\n                \"No obvious bugs or edge case failures\",\n                \"Has error handling for common failures\",\n                \"Variables and functions have clear, descriptive names\",\n                \"Has docstrings\/comments for complex logic\",\n                \"Time complexity is reasonable\",\n                \"No hardcoded secrets or credentials\",\n                \"Follows language best practices\"\n            ],\n            max_iterations=3,\n            quality_threshold=8\n        )\n        self.language = language\n\n    def _generate(self, task, previous_output, feedback_history):\n        if not previous_output:\n            prompt = f\"Write {self.language} code for: {task}\"\n        else:\n            feedback_text = \"\n\".join(feedback_history)\n            prompt = f\"\"\"Fix and improve this {self.language} code.\n\nOriginal task: {task}\n\nCurrent code:\n{previous_output}\n\nIssues to fix:\n{feedback_text}\n\nProvide the complete improved code.\"\"\"\n\n        response = client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=4000,\n            system=f\"You are an expert {self.language} developer. Write production-quality code.\",\n            messages=[{\"role\": \"user\", \"content\": prompt}]\n        )\n        return response.content[0].text\n\ncode_optimizer = CodeOptimizer(\n    language=\"Python\",\n    task=\"\"\"Create a rate-limited API client class that:\n- Makes HTTP requests with retry logic\n- Respects rate limits (max 10 req\/second)\n- Handles 429 responses with exponential backoff\n- Logs all requests and errors\"\"\"\n)\n\nresult = code_optimizer.run()\nprint(result['output'])\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eVí dụ 3: Translation Quality Loop\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef translation_optimizer(source_text: str, target_language: str = \"Vietnamese\"):\n    \"\"\"Tối ưu bản dịch qua nhiều vòng lặp\"\"\"\n\n    optimizer = EvaluatorOptimizer(\n        task_description=f\"\"\"Translate this text to {target_language}:\n\n{source_text}\"\"\",\n\n        evaluation_criteria=[\n            \"Meaning is fully preserved — no information lost\",\n            \"Natural, fluent language (not robotic machine translation)\",\n            \"Technical terms are translated consistently\",\n            \"Tone matches the original (formal\/casual)\",\n            f\"Grammar is correct {target_language}\",\n            \"Cultural adaptations are appropriate\",\n            \"No untranslated segments remain\"\n        ],\n        max_iterations=3,\n        quality_threshold=9  # Translation cần tiêu chuẩn cao hơn\n    )\n\n    return optimizer.run()\n\ntext_to_translate = \"\"\"\nThe Evaluator-Optimizer pattern represents a significant advancement\nin agentic AI systems. Rather than accepting first-pass outputs,\nthis pattern implements a quality feedback loop that mirrors\nhuman revision processes, leading to substantially better results.\n\"\"\"\n\nresult = translation_optimizer(text_to_translate)\nprint(result['output'])\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eAdvanced: Async Evaluator-Optimizer\u003c\/h2\u003e\n\n\u003cp\u003eKhi cần xử lý nhiều items song song, mỗi item có riêng feedback loop:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport asyncio\nimport anthropic\n\nasync_client = anthropic.AsyncAnthropic()\n\nasync def async_optimize_batch(tasks: list[str], max_iter: int = 3) -\u0026gt; list[dict]:\n    \"\"\"Optimize nhiều tasks song song, mỗi task có loop riêng\"\"\"\n\n    async def optimize_single(task: str, task_id: int) -\u0026gt; dict:\n        current = None\n        feedback_hist = []\n\n        for i in range(max_iter):\n            # Generate\n            gen_prompt = task if not current else f\"\"\"\nTask: {task}\nPrevious: {current}\nFeedback: {chr(10).join(feedback_hist)}\nImprove:\"\"\"\n\n            gen = await async_client.messages.create(\n                model=\"claude-haiku-4-5\",\n                max_tokens=1000,\n                messages=[{\"role\": \"user\", \"content\": gen_prompt}]\n            )\n            current = gen.content[0].text\n\n            # Evaluate\n            eval_r = await async_client.messages.create(\n                model=\"claude-haiku-4-5\",\n                max_tokens=200,\n                messages=[{\n                    \"role\": \"user\",\n                    \"content\": f\"Rate this output 1-10 and give brief feedback.\nTask: {task}\nOutput: {current}\nRespond: SCORE:X FEEDBACK:...\"\n                }]\n            )\n            eval_text = eval_r.content[0].text\n\n            try:\n                score = int(eval_text.split(\"SCORE:\")[1].split()[0])\n            except Exception:\n                score = 5\n\n            if score \u0026gt;= 8:\n                return {\"id\": task_id, \"output\": current, \"score\": score, \"iterations\": i+1}\n\n            feedback_hist.append(eval_text)\n\n        return {\"id\": task_id, \"output\": current, \"score\": score, \"iterations\": max_iter}\n\n    tasks_coroutines = [optimize_single(task, i) for i, task in enumerate(tasks)]\n    return await asyncio.gather(*tasks_coroutines)\n\n# Chạy\ntasks = [\n    \"Write a tweet about AI in healthcare\",\n    \"Write a tweet about climate change solutions\",\n    \"Write a tweet about remote work productivity\"\n]\nresults = asyncio.run(async_optimize_batch(tasks))\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eMetrics và Monitoring\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef analyze_optimization_history(history: list[dict]) -\u0026gt; dict:\n    \"\"\"Phân tích hiệu quả của optimization loop\"\"\"\n    if not history:\n        return {}\n\n    scores = [h[\"score\"] for h in history]\n    improvements = [scores[i+1] - scores[i] for i in range(len(scores)-1)]\n\n    return {\n        \"initial_score\": scores[0],\n        \"final_score\": scores[-1],\n        \"total_improvement\": scores[-1] - scores[0],\n        \"iterations\": len(history),\n        \"avg_improvement_per_round\": sum(improvements) \/ len(improvements) if improvements else 0,\n        \"best_iteration\": max(range(len(scores)), key=lambda i: scores[i]) + 1,\n        \"diminishing_returns\": improvements[-1] \u0026lt; improvements[0] if len(improvements) \u0026gt;= 2 else None\n    }\n\nresult = optimizer.run()\nstats = analyze_optimization_history(result[\"history\"])\nprint(f\"Improved from {stats['initial_score']} to {stats['final_score']} in {stats['iterations']} iterations\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eKhi nào dùng Evaluator-Optimizer\u003c\/h2\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003eScenario\u003c\/th\u003e\n\u003cth\u003ePhù hợp?\u003c\/th\u003e\n\u003cth\u003eLý do\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n\u003ctd\u003eContent marketing\u003c\/td\u003e\n\u003ctd\u003eRất phù hợp\u003c\/td\u003e\n\u003ctd\u003eQuality subjective, cần iterate\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eCode generation\u003c\/td\u003e\n\u003ctd\u003eRất phù hợp\u003c\/td\u003e\n\u003ctd\u003eBugs có thể fix qua feedback\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eTranslation\u003c\/td\u003e\n\u003ctd\u003ePhù hợp\u003c\/td\u003e\n\u003ctd\u003eFluency cải thiện qua review\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eData extraction\u003c\/td\u003e\n\u003ctd\u003eÍt phù hợp\u003c\/td\u003e\n\u003ctd\u003eĐúng\/sai rõ ràng, không cần loop\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eSimple Q\u0026amp;A\u003c\/td\u003e\n\u003ctd\u003eKhông phù hợp\u003c\/td\u003e\n\u003ctd\u003eOverkill, tốn tokens không cần thiết\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eReal-time chat\u003c\/td\u003e\n\u003ctd\u003eKhông phù hợp\u003c\/td\u003e\n\u003ctd\u003eLatency quá cao\u003c\/td\u003e\n\u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003ch2\u003eTổng kết\u003c\/h2\u003e\n\n\u003cp\u003eEvaluator-Optimizer là pattern mạnh nhất khi output quality là ưu tiên hàng đầu. Pattern này tự động hóa quá trình review-revise mà thông thường cần human editorial judgment.\u003c\/p\u003e\n\n\u003cp\u003eKey insights:\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eEvaluator cần criteria cụ thể, không mơ hồ — \"good writing\" không đủ, cần \"150 words, 3 features mentioned, CTA present\"\u003c\/li\u003e\n  \u003cli\u003eDùng model nhỏ hơn (haiku) cho evaluator để tiết kiệm chi phí\u003c\/li\u003e\n  \u003cli\u003e3-4 iterations thường là điểm tối ưu — sau đó returns giảm dần\u003c\/li\u003e\n  \u003cli\u003eLog history để phân tích và improve prompts\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eXem thêm: \u003ca href=\"\/collections\/nang-cao\"\u003eOrchestrator-Workers Pattern\u003c\/a\u003e để kết hợp cả hai pattern cho tasks phức tạp nhất.\u003c\/p\u003e\n\n\u003chr\u003e\n\u003ch3\u003eBài viết liên quan\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"\/products\/xay-d%E1%BB%B1ng-llm-agent-t%E1%BB%AB-d%E1%BA%A7u-reference-implementation\"\u003eXây dựng LLM Agent từ đầu — Reference Implementation\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/tool-evaluation-danh-gia-hi%E1%BB%87u-qu%E1%BA%A3-tools-trong-agent-systems\"\u003eTool Evaluation — Đánh giá hiệu quả tools trong agent systems\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/voice-assistant-v%E1%BB%9Bi-elevenlabs-claude-tr%E1%BB%A3-ly-gi%E1%BB%8Dng-noi\"\u003eVoice Assistant với ElevenLabs + Claude — Trợ lý giọng nói\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/autonomous-coding-agent-ai-t%E1%BB%B1-vi%E1%BA%BFt-code-t%E1%BB%AB-spec\"\u003eAutonomous Coding Agent — AI tự viết code từ spec\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/products\/claude-plugins-t%E1%BA%A1o-cowork-plugin-tuy-ch%E1%BB%89nh\"\u003eClaude Plugins: Tạo Cowork Plugin tùy chỉnh\u003c\/a\u003e\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721897066708,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/evaluator-optimizer-t_-c_i-thi_n-output-v_i-feedback-loop_12923e35-94f1-4097-a362-d51dd49d88a8.jpg?v=1774521762","url":"https:\/\/claude.vn\/products\/evaluator-optimizer-t%e1%bb%b1-c%e1%ba%a3i-thi%e1%bb%87n-output-v%e1%bb%9bi-feedback-loop","provider":"CLAUDE.VN","version":"1.0","type":"link"}