Cài đặt

Ngôn ngữ

Xây dựng AI Agent với nhiều Model: Hướng dẫn kiến trúc thực tiễn

L
LemonData
·26 tháng 2, 2026·425 lượt xem
Xây dựng AI Agent với nhiều Model: Hướng dẫn kiến trúc thực tiễn

Hầu hết các AI agent hiện nay đều sử dụng một model duy nhất cho mọi tác vụ. Từ bước lập kế hoạch, gọi tool, tóm tắt cho đến khôi phục lỗi. Cách tiếp cận này có thể ổn với các bản demo, nhưng trong môi trường production, nó cực kỳ lãng phí.

Một bước lập kế hoạch đòi hỏi khả năng lập luận sâu sắc không nhất thiết phải dùng chung một model với bước trích xuất JSON. Một tác vụ tạo code có những yêu cầu khác biệt so với một tác vụ phân loại. Việc sử dụng Claude Opus 4.6 ($25/1 triệu output token) chỉ để định dạng một chuỗi ngày tháng giống như việc thuê một kiến trúc sư trưởng chỉ để sơn một bức tường.

Dưới đây là cách xây dựng các agent có khả năng định tuyến (route) từng bước đến model tối ưu nhất.

Nếu bạn đang làm việc ở lớp API thay vì lớp agent, hãy đọc thêm bài Thiết kế API ưu tiên AgentTại sao các đội ngũ chuyển từ API Model trực tiếp sang Unified AI API cùng với trang này. Các agent đa model hoạt động tốt nhất khi bề mặt API bên dưới đủ ổn định để hoán đổi các model mà không cần viết lại mã điều phối (orchestration code).

Kiến trúc Agent Đa Model (Multi-Model Agent)

Yêu cầu người dùng
    │
    ▼
┌─────────────┐
│   Router     │  ← Phân loại độ phức tạp tác vụ
│ (model nhanh)│
└──────┬──────┘
       │
   ┌───┴───┐
   ▼       ▼
┌──────┐ ┌──────┐
│Model │ │Model │
│Đơn giản│ │Phức tạp│
└──┬───┘ └──┬───┘
   │        │
   ▼        ▼
┌─────────────┐
│ Aggregator  │  ← Kết hợp các kết quả
│ (model nhanh)│
└─────────────┘

Ba thành phần chính:

  1. Một router phân loại các tác vụ đầu vào theo độ phức tạp
  2. Một nhóm (pool) các model phù hợp với các loại tác vụ khác nhau
  3. Một aggregator kết hợp các kết quả khi cần thiết

Trong thực tế, các agent ở môi trường production thường cần thêm hai phần nữa:

  1. Chính sách fallback khi model ưu tiên bị lỗi hoặc phản hồi chậm
  2. Lớp telemetry ghi lại lựa chọn model, latency và chi phí cho mỗi bước

Nếu thiếu hai phần này, một agent đa model sẽ nhanh chóng trở thành một "hộp đen" với những hành vi không thể dự đoán trước.

Triển khai với OpenAI SDK

Bằng cách sử dụng một API key duy nhất thông qua một bộ tổng hợp, bạn có thể truy cập tất cả các model mà không cần quản lý nhiều SDK khác nhau:

from openai import OpenAI

client = OpenAI(
    api_key="sk-lemon-xxx",
    base_url="https://api.lemondata.cc/v1"
)

# Nhóm model với các cấp độ chi phí/năng lực
MODELS = {
    "router": "gpt-4.1-mini",        # $0.40/1M in - phân loại nhanh
    "simple": "gpt-4.1-mini",         # $0.40/1M in - trích xuất, định dạng
    "reasoning": "claude-sonnet-4-6",  # $3.00/1M in - lập kế hoạch, phân tích
    "complex": "gpt-4.1",             # $2.00/1M in - tạo code, giải quyết đa bước
    "budget": "deepseek-chat",         # $0.28/1M in - xử lý hàng loạt
}

def route_task(task: str) -> str:
    """Sử dụng một model rẻ để phân loại độ phức tạp của tác vụ."""
    response = client.chat.completions.create(
        model=MODELS["router"],
        messages=[
            {"role": "system", "content": """Phân loại tác vụ này vào một danh mục:
- simple: trích xuất dữ liệu, định dạng, dịch thuật
- reasoning: phân tích, lập kế hoạch, so sánh
- complex: tạo code, giải quyết vấn đề đa bước
- budget: xử lý hàng loạt, các tác vụ không quan trọng
Chỉ phản hồi tên danh mục."""},
            {"role": "user", "content": task}
        ],
        max_tokens=10
    )
    category = response.choices[0].message.content.strip().lower()
    return MODELS.get(category, MODELS["simple"])

def execute_task(task: str, context: str = "") -> str:
    """Định tuyến tác vụ đến model phù hợp và thực thi."""
    model = route_task(task)
    messages = []
    if context:
        messages.append({"role": "system", "content": context})
    messages.append({"role": "user", "content": task})

    response = client.chat.completions.create(
        model=model,
        messages=messages
    )
    return response.choices[0].message.content

Agent trong thực tế: Pipeline Review Code

Dưới đây là một agent đa model thực tế dùng để review các pull request:

def review_pr(diff: str) -> dict:
    """Pipeline review PR đa model."""

    # Bước 1: Phân loại các thay đổi (model rẻ)
    classification = client.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[{
            "role": "user",
            "content": f"Phân loại các thay đổi code này: {diff[:2000]}\n"
                       "Danh mục: bugfix, feature, refactor, docs, test"
        }],
        max_tokens=20
    ).choices[0].message.content

    # Bước 2: Quét bảo mật (model lập luận tốt)
    security = client.chat.completions.create(
        model="claude-sonnet-4-6",
        messages=[{
            "role": "system",
            "content": "Bạn là một chuyên gia review bảo mật. Hãy kiểm tra: "
                       "SQL injection, XSS, auth bypass, lộ secret trong code, "
                       "deserialization không an toàn. Hãy chỉ rõ số dòng cụ thể."
        }, {
            "role": "user",
            "content": f"Review diff này để tìm các vấn đề bảo mật:\n{diff}"
        }]
    ).choices[0].message.content

    # Bước 3: Chất lượng code (model tổng quát)
    quality = client.chat.completions.create(
        model="gpt-4.1",
        messages=[{
            "role": "user",
            "content": f"Review chất lượng code: cách đặt tên, cấu trúc, "
                       f"xử lý lỗi, độ bao phủ của test.\n{diff}"
        }]
    ).choices[0].message.content

    # Bước 4: Tóm tắt (model rẻ)
    summary = client.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[{
            "role": "user",
            "content": f"Tóm tắt bản review PR này thành 3 đầu dòng:\n"
                       f"Loại: {classification}\n"
                       f"Bảo mật: {security[:500]}\n"
                       f"Chất lượng: {quality[:500]}"
        }]
    ).choices[0].message.content

    return {
        "classification": classification,
        "security": security,
        "quality": quality,
        "summary": summary
    }

Phân bổ chi phí cho một lượt review PR điển hình (diff 2K token):

Bước Model Input Tokens Chi phí
Phân loại GPT-4.1-mini ~2,100 $0.0008
Bảo mật Claude Sonnet 4.6 ~2,500 $0.0075
Chất lượng GPT-4.1 ~2,500 $0.0050
Tóm tắt GPT-4.1-mini ~1,200 $0.0005
Tổng cộng ~$0.014

Nếu sử dụng Claude Sonnet 4.6 cho cả bốn bước, chi phí sẽ vào khoảng ~$0.028. Cách tiếp cận đa model giúp cắt giảm 50% chi phí trong khi vẫn sử dụng model mạnh nhất cho những phần quan trọng nhất (review bảo mật).

Định tuyến theo năng lực, không chỉ theo giá cả

Nhiều đội ngũ bắt đầu định tuyến đa model với một quy tắc đơn giản: tác vụ đắt tiền dùng model đắt tiền, tác vụ rẻ tiền dùng model rẻ tiền.

Đó là bước khởi đầu tốt, nhưng chưa đủ.

Một chính sách định tuyến mạnh mẽ hơn cần xem xét bốn khía cạnh:

  • độ sâu lập luận (reasoning depth)
  • độ dài ngữ cảnh (context length)
  • độ tin cậy khi sử dụng tool (tool-use reliability)
  • độ nhạy cảm với độ trễ (latency sensitivity)

Từ đó dẫn đến các quy tắc tốt hơn:

  • lập kế hoạch và phân rã tác vụ nên giao cho model thiên về lập luận
  • trích xuất và định dạng nên giao cho model rẻ và nhanh
  • review code nên giao cho model có khả năng tìm lỗi tốt nhất
  • phân tích toàn bộ repo nên giao cho model có context window lớn nhất

Đây cũng là lý do tại sao các bài so sánh model lập trìnhso sánh giá cả nên là thông tin đầu vào cho router của bạn thay vì chỉ nằm trong một thư mục nghiên cứu riêng biệt.

Tích hợp LangChain

from langchain_openai import ChatOpenAI

# Tạo các instance model với cấu hình khác nhau
fast = ChatOpenAI(
    model="gpt-4.1-mini",
    api_key="sk-lemon-xxx",
    base_url="https://api.lemondata.cc/v1"
)

reasoning = ChatOpenAI(
    model="claude-sonnet-4-6",
    api_key="sk-lemon-xxx",
    base_url="https://api.lemondata.cc/v1"
)

# Sử dụng trong các LangChain chain
from langchain_core.prompts import ChatPromptTemplate

classify_chain = ChatPromptTemplate.from_template(
    "Classify: {input}"
) | fast

analyze_chain = ChatPromptTemplate.from_template(
    "Analyze in depth: {input}"
) | reasoning

Khi nào nên sử dụng Agent Đa Model

Định tuyến đa model làm tăng độ phức tạp. Nó chỉ xứng đáng khi:

  • Agent của bạn xử lý các loại tác vụ đa dạng (không chỉ là chat)
  • Chi phí API hàng tháng vượt quá $100 (tiết kiệm trở nên có ý nghĩa)
  • Bạn cần những thế mạnh cụ thể của từng model (Claude cho code, Gemini cho context dài, GPT cho tốc độ)
  • Độ trễ (latency) quan trọng đối với một số bước nhưng không quan trọng với các bước khác

Đối với các chatbot đơn giản hoặc agent đơn mục tiêu, một model duy nhất là đủ. Chi phí vận hành của việc định tuyến không được bù đắp khi mọi request đều cần cùng một mức năng lực.

Điểm bùng phát thường là một trong những trường hợp sau:

  • bạn đang trả tiền cho khả năng lập luận cao cấp cho các tác vụ giá trị thấp
  • sự cố ngừng hoạt động của một nhà cung cấp hiện là rủi ro kinh doanh thực sự
  • nhu cầu về ngữ cảnh thay đổi rất lớn giữa các bước trong workflow
  • bạn cần các giai đoạn review / trích xuất / tóm tắt rẻ tiền bao quanh một giai đoạn cốt lõi đắt tiền

Nếu không có điều nào ở trên đúng, một model duy nhất vẫn là câu trả lời chính xác.

Các lỗi thường gặp

Hệ thống đa model thường thất bại theo những cách có thể dự đoán được:

1. Router quá "thông minh"

Nếu prompt của router trở thành một bài tập phân loại khổng lồ, bạn sẽ tốn quá nhiều chi phí chỉ để quyết định xem nên làm gì. Hãy giữ cho router rẻ và phân loại ở mức khái quát.

2. Hợp đồng đầu ra (output contracts) bị sai lệch

Một model trả về JSON sạch, model khác trả về văn bản kèm theo một khối JSON, và bộ parser phía sau của bạn bị lỗi. Hãy sử dụng schema rõ ràng và thực hiện validation tại mọi điểm bàn giao dữ liệu.

3. Fallback thay đổi chất lượng một cách âm thầm

Việc định tuyến sang một model rẻ hơn khi nhà cung cấp chính gặp áp lực có thể khiến agent trông có vẻ thiếu ổn định nếu người dùng nhận thấy chất lượng thay đổi hoàn toàn. Đó là lý do tại sao chiến lược rate limiting cần nằm trong thiết kế ngay từ đầu, chứ không phải là một ý tưởng bổ sung sau này.

4. Thiếu báo cáo chi phí

Nếu bạn không ghi lại lựa chọn model, chi phí và latency cho từng bước, bạn sẽ không thể biết liệu thiết kế đa model có thực sự tiết kiệm tiền hay không.

Một vòng lặp đánh giá tối giản

Bạn không cần một nền tảng đánh giá (eval) khổng lồ để vận hành một agent đa model một cách có trách nhiệm.

Hãy bắt đầu với một bảng tính hoặc một bảng database cho mỗi lần chạy:

  • danh mục tác vụ của người dùng
  • quyết định của router
  • model cuối cùng được sử dụng cho mỗi bước
  • latency mỗi bước
  • tổng chi phí token
  • liệu fallback có được kích hoạt hay không
  • liệu người dùng có chấp nhận câu trả lời hay không

Điều đó cung cấp cho bạn đủ tín hiệu để trả lời các câu hỏi quan trọng:

  • Router có chọn đúng model đắt tiền đủ thường xuyên không?
  • Bước nào đang tiêu tốn phần lớn ngân sách?
  • Các fallback đang cứu vãn hệ thống hay chỉ đang che giấu sự bất ổn?
  • Lộ trình giá rẻ có đủ tốt cho các tác vụ lặp đi lặp lại không?

Đây cũng là lý do tại sao một gateway thống nhất lại hữu ích. Khi việc sử dụng model rải rác ở nhiều nhà cung cấp, việc tập hợp một sổ cái vận hành có thể so sánh được sẽ khó khăn hơn. Khi mọi thứ đi qua một lớp API duy nhất, gánh nặng về đo lường (instrumentation) sẽ giảm xuống.

Giữ cho kiến trúc "nhàm chán" (ổn định)

Những agent đa model tốt nhất không mang lại cảm giác xa lạ. Chúng mang lại cảm giác ổn định về mặt vận hành.

Điều đó có nghĩa là:

  • một cấu trúc request ổn định đi vào lớp điều phối (orchestration layer) của bạn
  • một nơi duy nhất để định nghĩa các quy tắc định tuyến
  • một nơi duy nhất để kiểm tra chi phí và latency
  • một chính sách fallback cho mỗi nhóm tác vụ
  • một nguồn sự thật duy nhất cho danh sách model được phép (allowlists)

Nếu sơ đồ agent của bạn trông có vẻ thông minh nhưng những người vận hành không thể giải thích tại sao một request lại được gửi đến model này thay vì model kia, thì thiết kế đó vẫn chưa hoàn thiện.

Khi nào không nên sử dụng Agent Đa Model

Cũng có những trường hợp rõ ràng mà thiết kế đơn giản hơn sẽ giành chiến thắng.

Đừng thêm định tuyến chỉ vì danh mục model quá lớn.

Hãy trung thành với một model duy nhất khi:

  • sản phẩm chỉ thực hiện một tác vụ hẹp lặp đi lặp lại
  • sự khác biệt về chất lượng giữa các model không quan trọng đối với người dùng
  • lưu lượng truy cập của bạn quá thấp để việc tối ưu hóa chi phí có ý nghĩa
  • hệ thống vận hành của bạn chưa được đo lường đầy đủ
  • bạn chưa có hệ thống đánh giá (evals) đủ mạnh để biết liệu định tuyến có giúp ích hay gây hại

Một model duy nhất được lựa chọn kỹ lưỡng với cơ chế retry tốt, prompt sạch sẽ và khả năng quan sát (observability) thường đánh bại một sơ đồ đa model hào nhoáng mà không ai tin tưởng.

Câu hỏi đúng không phải là “chúng ta có thể định tuyến không?” mà là “việc định tuyến có tạo ra chất lượng tốt hơn, chi phí thấp hơn hoặc hành vi xử lý lỗi an toàn hơn cho workflow này không?”

Nếu câu trả lời còn mơ hồ, hãy giữ kiến trúc đơn giản cho đến khi bản thân workflow trở nên đa dạng hơn.

Những điểm chính cần lưu ý

  1. Sử dụng model rẻ nhất có thể xử lý tốt từng bước
  2. Dành các model đắt tiền cho các tác vụ thực sự cần đến chúng
  3. Các bước phân loại/định tuyến luôn nên sử dụng model rẻ nhất hiện có
  4. Đo lường chi phí thực tế trên mỗi lần chạy agent, không chỉ giá trên mỗi token
  5. Một API aggregator với một key duy nhất giúp đơn giản hóa đáng kể việc truy cập đa model

Agent đa model không vốn dĩ tốt hơn. Chúng chỉ tốt hơn khi workflow thực sự chứa đựng các loại công việc khác nhau.


Truy cập mọi model thông qua một API duy nhất: LemonData cung cấp hơn 300 model với một API key duy nhất. Xây dựng các agent đa model mà không cần quản lý nhiều tài khoản nhà cung cấp hoặc phải thiết kế lại cơ chế định tuyến cho mỗi cặp nhà cung cấp.

Share: