Một nền tảng agent tốt trông như một sân bay: mỗi máy bay (agent) tự bay, nhưng tất cả cất/hạ cánh qua đài kiểm soát chung. Bài này mô tả reference architecture gồm các lớp bạn nên tách bạch để dễ nâng cấp và kiểm soát.
Sáu lớp của nền tảng
[1] Agent Runtime (nơi agent chạy: container, function)
[2] Agent Framework/SDK (chuẩn viết agent: tool, memory, planner)
[3] Model Gateway (1 cửa gọi mọi LLM: routing, cache, quota)
[4] Tool/Integration (kết nối hệ thống: CRM, DB, email - có scope)
[5] Guardrails & Policy (lọc input/output, kiểm quyền, PII)
[6] Observability & Governance (log, trace, cost, registry)
Nguyên tắc vàng: mọi lời gọi LLM và mọi lời gọi tool đều phải đi qua lớp có thể quan sát và chặn được. Nếu một agent gọi thẳng api.openai.com, bạn mất quyền kiểm soát.
Model Gateway: trái tim của nền tảng
Gateway là một service đứng giữa agent và các nhà cung cấp model. Ví dụ cấu hình định tuyến:
# gateway-routes.yaml
routes:
- name: default-chat
match: { capability: chat }
primary: { provider: anthropic, model: claude-sonnet }
fallback: { provider: openai, model: gpt-4o-mini }
limits: { rpm: 300, max_tokens: 4000 }
- name: cheap-classify
match: { capability: classify }
primary: { provider: local, model: qwen-7b }
policies:
redact_pii: true
log_prompts: sampled # lưu 10% để debug, không lưu hết
Lợi ích: đổi model không cần sửa code agent, ép quota theo team, cache câu hỏi lặp, gắn team_id vào mọi request để tính chi phí.
Cách agent gọi qua gateway (SDK)
from platform_sdk import Agent, tool
@tool(scopes=["crm:read"]) # khai báo quyền tối thiểu
def lookup_customer(email: str) -> dict:
return crm.get(email)
agent = Agent(
name="support-summarizer",
capability="chat", # gateway tự chọn model
tools=[lookup_customer],
guardrails="default", # bật bộ guardrails chuẩn
)
agent.run("Tóm tắt ticket #482 cho khách")
Agent không biết đang dùng model nào, không giữ API key, không tự log — nền tảng lo hết.
Các bước dựng kiến trúc tối thiểu (MVP)
- Dựng Model Gateway trước tiên (dùng LiteLLM, Portkey, hoặc tự viết proxy) và ép mọi POC hiện có trỏ vào nó.
- Phát hành SDK/template mỏng bọc quanh framework bạn chọn (LangGraph, CrewAI...).
- Bật observability: mọi request có
trace_id,team_id, token, latency. - Thêm lớp tool có scope: tool khai báo quyền, nền tảng cấp phát khi duyệt.
- Cắm guardrails vào gateway để bật mặc định, không phụ thuộc agent tự nhớ.
Vì sao tách lớp lại quan trọng đến vậy?
Hãy tưởng tượng sáu tháng sau bạn muốn đổi từ một nhà cung cấp model sang nhà cung cấp khác vì giá tốt hơn, hoặc muốn thêm một bộ guardrails mới cho toàn bộ agent. Nếu mọi thứ dính chặt vào nhau, bạn phải sửa từng agent một — có thể là hàng chục repo khác nhau, mỗi cái do một team khác nhau bảo trì. Nếu các lớp được tách bạch, bạn chỉ sửa ở đúng một lớp: đổi model thì sửa Gateway, thêm guardrail thì sửa lớp Policy, và toàn bộ agent tự động hưởng lợi mà không đụng tới một dòng code nghiệp vụ nào. Đây chính là lý do các nền tảng trưởng thành luôn đầu tư tách lớp ngay từ đầu: chi phí thay đổi trong tương lai được kéo xuống thấp.
Một hệ quả thực tế khác: khi có sự cố bảo mật, việc tách lớp cho phép bạn xác định nhanh phạm vi ảnh hưởng. Ví dụ nếu một scope tool bị lộ, bạn tra ở lớp Tool/Integration xem những agent nào đang được cấp scope đó, thay vì phải rà từng agent thủ công. Lớp Governance ở tầng dưới cùng chính là nơi tổng hợp mọi thông tin này thành một bức tranh thống nhất.
Khung tư duy: quyết định build vs buy
- Gateway: nên dùng sản phẩm có sẵn trước (LiteLLM/Portkey), tự viết sau nếu cần đặc thù.
- Framework agent: chọn 1 chuẩn (đừng để 4 team 4 framework), nhưng giữ lớp Gateway trung lập để không bị khóa vào framework đó.
- Observability: LangSmith/Langfuse/Phoenix — chọn cái tích hợp OpenTelemetry để không bị khóa nhà cung cấp.
- Nguyên tắc chung: mua phần hạ tầng đã chuẩn hóa (gateway, tracing), tự xây phần tạo lợi thế riêng (template nghiệp vụ, guardrails đặc thù ngành của bạn).
Sai lầm thường gặp
- Cho agent giữ API key trực tiếp: mất kiểm soát chi phí và bảo mật ngay lập tức.
- Nhồi mọi thứ vào một service khổng lồ: khó nâng cấp; hãy tách 6 lớp.
- Bỏ qua trace_id xuyên suốt: khi agent lỗi trong production bạn không lần được chuỗi tool đã gọi.
- Ép một framework agent quá sớm cho mọi loại bài toán: agent hội thoại và agent batch có nhu cầu khác nhau; hãy để SDK trung lập ở lớp gateway.