{"product_id":"agent-workflows-chaining-routing-parallelization","title":"Agent Workflows — Chaining, Routing, Parallelization","description":"\n\u003cp\u003eAnthropic đã tổng kết kinh nghiệm xây dựng hàng trăm AI applications vào \u003cstrong\u003e5 agentic patterns\u003c\/strong\u003e cơ bản. Đây là những \"design patterns\" cho AI workflows — giống như Factory, Observer hay Strategy pattern trong lập trình hướng đối tượng, nhưng dành cho LLM systems.\u003c\/p\u003e\n\n\u003cp\u003eHiểu và áp dụng đúng 5 patterns này sẽ giúp bạn xây dựng AI applications phức tạp một cách có cấu trúc, dễ maintain và scale.\u003c\/p\u003e\n\n\u003ch2\u003eTại sao cần Agentic Patterns?\u003c\/h2\u003e\n\n\u003cp\u003eMột LLM call đơn lẻ có giới hạn: context window hữu hạn, không thể parallelize, không có feedback loop. Agentic patterns giải quyết những hạn chế này bằng cách \u003cstrong\u003eorchestrate nhiều LLM calls\u003c\/strong\u003e thành pipeline thông minh.\u003c\/p\u003e\n\n\u003ch2\u003ePattern 1: Prompt Chaining (Chuỗi xử lý tuần tự)\u003c\/h2\u003e\n\n\u003cp\u003eChia task phức tạp thành nhiều bước tuần tự, output của bước này là input của bước tiếp theo.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\n\nclient = anthropic.Anthropic()\n\ndef prompt_chain(document_text):\n    \"\"\"Pipeline 3 bước: Extract -\u0026gt; Translate -\u0026gt; Summarize\"\"\"\n\n    # Bước 1: Trích xuất thông tin chính\n    step1 = client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=2000,\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Extract key facts from this document.\nOutput as JSON with fields: main_topic, key_points (list), entities (list).\n\nDocument:\n{document_text}\"\"\"\n        }]\n    )\n    extracted = step1.content[0].text\n\n    # Bước 2: Dịch sang tiếng Việt\n    step2 = client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=2000,\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Translate this JSON data to Vietnamese.\nKeep the JSON structure exactly the same.\n\n{extracted}\"\"\"\n        }]\n    )\n    translated = step2.content[0].text\n\n    # Bước 3: Tạo executive summary\n    step3 = client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=500,\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Based on these extracted facts, write a 3-sentence executive summary in Vietnamese.\n\nFacts:\n{translated}\"\"\"\n        }]\n    )\n\n    return {\n        \"extracted\": extracted,\n        \"translated\": translated,\n        \"summary\": step3.content[0].text\n    }\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003e\u003cstrong\u003eKhi nào dùng Prompt Chaining:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eTask có các bước logic tự nhiên (extract → transform → generate)\u003c\/li\u003e\n  \u003cli\u003eKết quả trung gian cần kiểm tra hoặc lưu lại\u003c\/li\u003e\n  \u003cli\u003eMỗi bước dùng model khác nhau (haiku cho simple, opus cho complex)\u003c\/li\u003e\n  \u003cli\u003eMuốn retry từng bước độc lập khi có lỗi\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003ePattern 2: Routing (Phân loại và định tuyến)\u003c\/h2\u003e\n\n\u003cp\u003eMột LLM \"classifier\" phân tích input và quyết định route đến handler chuyên biệt nào.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef routing_agent(user_query):\n    \"\"\"Route câu hỏi đến specialist phù hợp\"\"\"\n\n    # Router: phân loại intent\n    router_response = client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=100,\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Classify this query into exactly one category:\n- TECHNICAL: code, bugs, API, architecture questions\n- BILLING: pricing, invoices, subscriptions\n- GENERAL: other questions\n\nQuery: {user_query}\n\nRespond with only the category name.\"\"\"\n        }]\n    )\n\n    category = router_response.content[0].text.strip()\n\n    # Specialist handlers\n    specialists = {\n        \"TECHNICAL\": handle_technical,\n        \"BILLING\": handle_billing,\n        \"GENERAL\": handle_general\n    }\n\n    handler = specialists.get(category, handle_general)\n    return handler(user_query)\n\ndef handle_technical(query):\n    return client.messages.create(\n        model=\"claude-opus-4-5\",  # Model mạnh hơn cho technical\n        max_tokens=4000,\n        system=\"You are a senior software engineer. Provide detailed technical answers with code examples.\",\n        messages=[{\"role\": \"user\", \"content\": query}]\n    ).content[0].text\n\ndef handle_billing(query):\n    return client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=1000,\n        system=\"You are a billing specialist. Be precise about pricing and refer to official documentation.\",\n        messages=[{\"role\": \"user\", \"content\": query}]\n    ).content[0].text\n\ndef handle_general(query):\n    return client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=1000,\n        messages=[{\"role\": \"user\", \"content\": query}]\n    ).content[0].text\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003e\u003cstrong\u003eKhi nào dùng Routing:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eNhiều loại câu hỏi\/task khác nhau với specialist xử lý tốt hơn\u003c\/li\u003e\n  \u003cli\u003eMuốn dùng model đắt tiền chỉ khi thực sự cần\u003c\/li\u003e\n  \u003cli\u003eCó domain expertise khác nhau cần áp dụng\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003ePattern 3: Parallelization (Xử lý song song)\u003c\/h2\u003e\n\n\u003cp\u003eChia task thành nhiều sub-tasks độc lập, chạy song song, rồi aggregate kết quả.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport asyncio\nimport anthropic\n\nasync_client = anthropic.AsyncAnthropic()\n\nasync def analyze_product_reviews(reviews: list[str]):\n    \"\"\"Phân tích nhiều reviews song song\"\"\"\n\n    async def analyze_single_review(review: str, review_id: int):\n        response = await async_client.messages.create(\n            model=\"claude-haiku-4-5\",\n            max_tokens=300,\n            messages=[{\n                \"role\": \"user\",\n                \"content\": f\"\"\"Analyze this review. Return JSON:\n{{\n  \"sentiment\": \"positive\/negative\/neutral\",\n  \"score\": 1-5,\n  \"key_issue\": \"main complaint or praise\",\n  \"actionable\": true\/false\n}}\n\nReview: {review}\"\"\"\n            }]\n        )\n        return {\"id\": review_id, \"analysis\": response.content[0].text}\n\n    # Chạy tất cả song song\n    tasks = [\n        analyze_single_review(review, i)\n        for i, review in enumerate(reviews)\n    ]\n    results = await asyncio.gather(*tasks)\n\n    # Aggregate\n    return aggregate_reviews(results)\n\ndef aggregate_reviews(results):\n    \"\"\"Tổng hợp kết quả từ tất cả reviews\"\"\"\n    # Trong production: parse JSON, tính stats, etc.\n    return {\n        \"total\": len(results),\n        \"results\": results\n    }\n\n# Gọi\nreviews = [\"Great product!\", \"Delivery was slow\", \"Amazing quality, worth the price\"]\nresults = asyncio.run(analyze_product_reviews(reviews))\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eFan-out\/Fan-in với Voting\u003c\/h3\u003e\n\u003cp\u003eMột biến thể của Parallelization: chạy cùng một task nhiều lần, voting để lấy kết quả tốt nhất:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003easync def parallel_with_voting(question: str, n_votes: int = 3):\n    \"\"\"Chạy N lần, lấy kết quả được vote nhiều nhất\"\"\"\n\n    async def single_run(run_id: int):\n        response = await async_client.messages.create(\n            model=\"claude-haiku-4-5\",\n            max_tokens=500,\n            temperature=0.7,  # Một chút randomness để đa dạng\n            messages=[{\"role\": \"user\", \"content\": question}]\n        )\n        return response.content[0].text\n\n    tasks = [single_run(i) for i in range(n_votes)]\n    answers = await asyncio.gather(*tasks)\n\n    # Voting: dùng LLM để chọn best answer\n    voting_prompt = f\"\"\"\nYou got {n_votes} different answers to the same question.\nChoose the best one and explain why.\n\nQuestion: {question}\n\nAnswers:\n\"\"\" + \"\n\".join([f\"{i+1}. {a}\" for i, a in enumerate(answers)])\n\n    final = await async_client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=500,\n        messages=[{\"role\": \"user\", \"content\": voting_prompt}]\n    )\n    return final.content[0].text\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003ePattern 4: Orchestrator-Workers\u003c\/h2\u003e\n\n\u003cp\u003eMột Orchestrator LLM động phân tích task và điều phối nhiều Worker LLMs chuyên biệt:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef orchestrator_workers(complex_task: str):\n    \"\"\"Orchestrator tạo kế hoạch, workers thực hiện\"\"\"\n\n    # Orchestrator: tạo execution plan\n    plan_response = client.messages.create(\n        model=\"claude-opus-4-5\",\n        max_tokens=2000,\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"You are an orchestrator. Break this task into subtasks.\nOutput JSON array of steps, each with:\n- step_id: number\n- description: what to do\n- worker_type: \"researcher\"\/\"writer\"\/\"coder\"\/\"analyst\"\n- depends_on: list of step_ids that must complete first\n\nTask: {complex_task}\"\"\"\n        }]\n    )\n\n    import json\n    plan = json.loads(plan_response.content[0].text)\n\n    # Execute theo dependency order\n    results = {}\n    for step in plan:\n        # Chờ dependencies\n        deps = step.get(\"depends_on\", [])\n        dep_context = {dep_id: results[dep_id] for dep_id in deps if dep_id in results}\n\n        # Gọi worker phù hợp\n        worker_result = call_worker(\n            step[\"worker_type\"],\n            step[\"description\"],\n            dep_context\n        )\n        results[step[\"step_id\"]] = worker_result\n\n    # Orchestrator tổng hợp\n    final = client.messages.create(\n        model=\"claude-opus-4-5\",\n        max_tokens=3000,\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"\"\"Synthesize these worker results into a final deliverable.\nOriginal task: {complex_task}\nResults: {json.dumps(results, ensure_ascii=False)}\"\"\"\n        }]\n    )\n    return final.content[0].text\n\ndef call_worker(worker_type: str, task: str, context: dict):\n    system_prompts = {\n        \"researcher\": \"You are a research specialist. Find facts and provide citations.\",\n        \"writer\": \"You are a professional writer. Create clear, engaging content.\",\n        \"coder\": \"You are a senior developer. Write clean, well-documented code.\",\n        \"analyst\": \"You are a data analyst. Provide quantitative insights.\"\n    }\n    return client.messages.create(\n        model=\"claude-haiku-4-5\",\n        max_tokens=2000,\n        system=system_prompts.get(worker_type, \"You are a helpful assistant.\"),\n        messages=[{\n            \"role\": \"user\",\n            \"content\": f\"Task: {task}\nContext from previous steps: {context}\"\n        }]\n    ).content[0].text\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003ePattern 5: Evaluator-Optimizer\u003c\/h2\u003e\n\n\u003cp\u003eGenerator tạo output, Evaluator đánh giá, loop cho đến khi đạt quality threshold:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef evaluator_optimizer(task: str, max_iterations: int = 3):\n    \"\"\"Tự cải thiện output qua nhiều vòng lặp\"\"\"\n    current_output = None\n    feedback_history = []\n\n    for iteration in range(max_iterations):\n        # Generator: tạo hoặc cải thiện output\n        gen_prompt = task if iteration == 0 else f\"\"\"\nTask: {task}\n\nPrevious attempt:\n{current_output}\n\nFeedback received:\n{chr(10).join(feedback_history)}\n\nPlease improve the output addressing all feedback points.\"\"\"\n\n        current_output = client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=3000,\n            messages=[{\"role\": \"user\", \"content\": gen_prompt}]\n        ).content[0].text\n\n        # Evaluator: chấm điểm và feedback\n        eval_response = client.messages.create(\n            model=\"claude-haiku-4-5\",\n            max_tokens=500,\n            messages=[{\n                \"role\": \"user\",\n                \"content\": f\"\"\"Evaluate this output for the task: {task}\n\nOutput:\n{current_output}\n\nRate 1-10 and list specific improvements needed.\nIf score \u0026gt;= 8, output APPROVED.\nFormat: SCORE: X\nFEEDBACK: ...\"\"\"\n            }]\n        ).content[0].text\n\n        if \"APPROVED\" in eval_response or \"SCORE: 9\" in eval_response or \"SCORE: 10\" in eval_response:\n            return {\"output\": current_output, \"iterations\": iteration + 1, \"approved\": True}\n\n        feedback_history.append(f\"Iteration {iteration + 1}: {eval_response}\")\n\n    return {\"output\": current_output, \"iterations\": max_iterations, \"approved\": False}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eChọn Pattern phù hợp\u003c\/h2\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003ePattern\u003c\/th\u003e\n\u003cth\u003eDùng khi\u003c\/th\u003e\n\u003cth\u003eĐộ phức tạp\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n\u003ctd\u003ePrompt Chaining\u003c\/td\u003e\n\u003ctd\u003eTask có steps rõ ràng, tuần tự\u003c\/td\u003e\n\u003ctd\u003eThấp\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eRouting\u003c\/td\u003e\n\u003ctd\u003eNhiều loại input, specialist xử lý tốt hơn\u003c\/td\u003e\n\u003ctd\u003eThấp\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eParallelization\u003c\/td\u003e\n\u003ctd\u003eTasks độc lập, cần tốc độ hoặc voting\u003c\/td\u003e\n\u003ctd\u003eTrung bình\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eOrchestrator-Workers\u003c\/td\u003e\n\u003ctd\u003eTask phức tạp, không biết trước steps\u003c\/td\u003e\n\u003ctd\u003eCao\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003eEvaluator-Optimizer\u003c\/td\u003e\n\u003ctd\u003eOutput quality quan trọng, cần iterate\u003c\/td\u003e\n\u003ctd\u003eTrung bình\u003c\/td\u003e\n\u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003cp\u003eĐọc chi tiết về từng pattern: \u003ca href=\"\/en\/collections\/nang-cao\"\u003eEvaluator-Optimizer Pattern\u003c\/a\u003e và \u003ca href=\"\/en\/collections\/nang-cao\"\u003eOrchestrator-Workers Architecture\u003c\/a\u003e.\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=\"\/en\/products\/evaluator-optimizer-t%E1%BB%B1-c%E1%BA%A3i-thi%E1%BB%87n-output-v%E1%BB%9Bi-feedback-loop\"\u003eEvaluator-Optimizer — Tự cải thiện output với feedback loop\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/speculative-caching-gi%E1%BA%A3m-time-to-first-token-v%E1%BB%9Bi-cache-d%E1%BB%B1-doan\"\u003eSpeculative Caching — Giảm time-to-first-token với cache dự đoán\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/content-moderation-xay-d%E1%BB%B1ng-b%E1%BB%99-l%E1%BB%8Dc-n%E1%BB%99i-dung-v%E1%BB%9Bi-claude\"\u003eContent Moderation — Xây dựng bộ lọc nội dung với Claude\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/context-engineering-ngh%E1%BB%87-thu%E1%BA%ADt-qu%E1%BA%A3n-ly-context-cho-claude\"\u003eContext Engineering — Nghệ thuật quản lý context cho Claude\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/claude-cho-engineering-incident-response-workflow\"\u003eClaude cho Engineering: Incident Response workflow\u003c\/a\u003e\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721896968404,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/agent-workflows-chaining-routing-parallelization.jpg?v=1774526582","url":"https:\/\/claude.vn\/en\/products\/agent-workflows-chaining-routing-parallelization","provider":"CLAUDE.VN","version":"1.0","type":"link"}