Bài 1: What Is an AI Agent?¶
Tổng quan¶
Bài này xây dựng nền tảng khái niệm cho toàn bộ Module II: agent là gì, khác gì với một lời gọi LLM đơn thuần hay một RAG pipeline cố định, các thành phần cấu thành nên một agent, cách cấu trúc system prompt cho agent phức tạp, và bức tranh landscape framework/protocol năm 2026.
1. Định nghĩa & Sự tiến hoá¶
Agent là gì?¶
Một AI agent là một hệ thống dùng LLM làm bộ não trung tâm để tự quyết định chuỗi hành động cần thực hiện nhằm đạt mục tiêu, thay vì đi theo một luồng xử lý cố định do lập trình viên viết sẵn.
Điểm khác biệt cốt lõi so với pipeline truyền thống: ai quyết định bước tiếp theo.
| Pipeline cố định (vd: RAG ở Module I) | Agent | |
|---|---|---|
| Luồng xử lý | Lập trình viên định nghĩa trước: retrieve → generate | LLM tự quyết định: cần tool nào, gọi mấy lần, khi nào dừng |
| Số bước | Cố định | Động, phụ thuộc vào kết quả trung gian |
| Khả năng phục hồi lỗi | Không - nếu retrieve rỗng, generate vẫn chạy | Có thể quan sát lỗi và thử cách khác |
RAG có phải là agent không?
RAG cơ bản (retrieve → generate) không phải agent - đó là pipeline cố định. Agentic RAG (Module I, Bài 6) đã bắt đầu mang tính agent vì model tự quyết định có cần retrieve lại hay tìm web không. Ranh giới nằm ở quyền tự quyết định hành động tiếp theo.
Sự tiến hoá¶
graph LR
A[2020-2022<br/>Prompt engineering<br/>1 lời gọi, output cố định] --> B[2023<br/>ReAct, Chain-of-Thought<br/>Reasoning + Action]
B --> C[2024<br/>Function calling chuẩn hoá<br/>LangChain, AutoGPT]
C --> D[2025<br/>Graph-based orchestration<br/>LangGraph, CrewAI, OpenAI Agents SDK]
D --> E[2026<br/>Protocol chuẩn hoá<br/>MCP, A2A, Multi-agent phổ biến]
A2A là gì?
Agent2Agent (A2A) là chuẩn giao tiếp giữa các agent với nhau (agent-to-agent), khác với MCP vốn chuẩn hoá giao tiếp giữa agent và tool/data source. A2A liên quan trực tiếp đến Multi-Agent Systems (Bài 6) nhưng nằm ngoài phạm vi module này - chỉ nhắc đến ở đây để định vị trong bức tranh landscape.
2. Core Components¶
Mọi agent, dù dùng framework nào, đều gồm 4 thành phần:
graph TD
subgraph Agent
BRAIN[LLM Brain<br/>Reasoning + Decision making]
TOOLS[Tools<br/>Function calling, APIs, RAG]
MEMORY[Memory<br/>Short-term + Long-term]
PLAN[Planning Loop<br/>Observe → Think → Act]
end
BRAIN <--> TOOLS
BRAIN <--> MEMORY
BRAIN --> PLAN
PLAN --> BRAIN
| Thành phần | Vai trò | Ví dụ |
|---|---|---|
| LLM Brain | Reasoning, ra quyết định, chọn hành động tiếp theo | GPT-4o, Claude, Gemini |
| Tools | Cầu nối với thế giới bên ngoài | Web search, database query, RAG retrieval, code execution |
| Memory | Giữ ngữ cảnh qua nhiều bước / nhiều lượt hội thoại | Conversation history, vector store, scratchpad |
| Planning Loop | Vòng lặp quan sát - suy nghĩ - hành động, quyết định khi nào dừng | ReAct loop, task decomposition |
Thiếu 1 thành phần vẫn có thể gọi là agent, nhưng giới hạn
Một chatbot chỉ có LLM Brain + Memory (không có Tools) chỉ có thể trò chuyện, không thể hành động. Một script gọi tool cố định (không có Planning Loop) là automation, không phải agent thực sự.
3. System Prompt: Cấu trúc & Cách lắp ráp¶
System prompt là nơi cấu hình "LLM Brain" - agent càng phức tạp, system prompt càng cần được lắp ráp có cấu trúc thay vì viết tay một đoạn văn dài.
6 tầng của một system prompt¶
| Tầng | Trả lời câu hỏi | Ví dụ |
|---|---|---|
| Identity | Agent là ai? | "Bạn là trợ lý kỹ thuật cấp cao chuyên về..." |
| Constraints | Luôn/không bao giờ làm gì? | "Không bao giờ thực thi lệnh phá huỷ dữ liệu mà chưa xác nhận" |
| Capabilities | Có tool gì? | Mô tả + schema của các tool khả dụng |
| Context | Môi trường hiện tại? | Thư mục làm việc, trạng thái git, thời gian |
| Behavior | Cư xử thế nào? | Tone, độ dài phản hồi, phong cách ra quyết định |
| Knowledge | Kiến thức chuyên biệt? | Skill instructions, memory liên quan (Bài 3) |
Lắp ráp theo từng phần, không viết 1 khối văn bản¶
def assemble_system_prompt(agent_config: dict, task: str, environment: dict) -> str:
sections = []
sections.append(agent_config["identity"]) # Luôn có
sections.append(agent_config["constraints"]) # Luôn có
sections.append(format_tools(select_tools(task, agent_config["tools"]))) # Lọc theo task
sections.append(format_environment(environment)) # Động, theo runtime
if agent_config.get("soul"):
sections.append(agent_config["soul"]) # Behavior, xem SOUL.md bên dưới
return "\n\n".join(sections)
Anti-pattern: nhồi tất cả vào 1 chuỗi
Viết system prompt như 1 đoạn văn dài chứa mọi thứ (identity + toàn bộ 50 tool + toàn bộ lịch sử user + 200 skill) không maintain được, không customize được theo task, và lãng phí token nghiêm trọng. Luôn lắp ráp từ các phần nhỏ, lọc theo nhu cầu hiện tại - giống cách JIT tool loading lọc tool theo task (Bài 4).
AGENTS.md vs SOUL.md: tách "làm gì" khỏi "là ai"¶
Với agent cá nhân hoá (vd: trợ lý dùng lâu dài, nhớ user qua nhiều session - Bài 3), tách system prompt thành 2 file riêng biệt giúp thay đổi tính cách mà không đụng vào logic vận hành, và ngược lại:
| File | Trả lời | Ví dụ nội dung |
|---|---|---|
| AGENTS.md | Agent làm gì, quy tắc vận hành | "Dùng web_search cho câu hỏi thực tế. Luôn xác nhận trước khi xoá dữ liệu." |
| SOUL.md | Agent cư xử ra sao, tính cách | "Trả lời trực tiếp rồi mới giải thích. Thừa nhận khi không chắc thay vì bịa." |
# AGENTS.md (vận hành - developer sở hữu)
## Quy tắc công cụ
- Dùng `search_vietnamese_news` cho câu hỏi thời sự
- Luôn xác nhận trước khi gọi tool có side effect
# SOUL.md (tính cách - user tuỳ chỉnh)
## Phong cách giao tiếp
- Trả lời ngắn gọn, đi thẳng vào trọng tâm
- Dùng ví dụ cụ thể thay vì giải thích trừu tượng
Lợi ích: User đổi tông giọng agent (SOUL.md) mà không sợ phá vỡ logic vận hành (AGENTS.md); developer thêm tool/quy tắc mới mà không ảnh hưởng tính cách đã được user tuỳ chỉnh.
Chỉ cần tách khi agent thực sự cá nhân hoá lâu dài
Với agent dùng 1 lần hoặc task-specific (đa số ví dụ trong module này), 1 system prompt đơn giản là đủ. Tách AGENTS.md/SOUL.md đáng giá khi agent phục vụ nhiều user với gu cá nhân khác nhau, hoặc khi đội ngũ vận hành và đội ngũ thiết kế trải nghiệm là 2 nhóm khác nhau.
4. Agent Paradigms¶
Reflex Agent¶
Phản ứng trực tiếp với input hiện tại, không có bộ nhớ về quá khứ, không lập kế hoạch nhiều bước.
def reflex_agent(user_input: str) -> str:
# Map input → action, không suy luận nhiều bước
if "thời tiết" in user_input:
return get_weather()
if "giá vàng" in user_input:
return get_gold_price()
return llm_respond(user_input)
Phù hợp khi: Task đơn giản, 1 bước, không cần ngữ cảnh trước đó.
Planning Agent¶
Trước khi hành động, agent lập kế hoạch toàn bộ các bước cần làm, rồi thực thi theo kế hoạch (có thể điều chỉnh khi gặp lỗi).
PLAN_PROMPT = """Nhiệm vụ: {task}
Hãy lập kế hoạch các bước cần thực hiện để hoàn thành nhiệm vụ.
Trả về danh sách bước theo thứ tự, mỗi bước là 1 hành động cụ thể.
"""
# LLM trả về:
# 1. Tìm kiếm thông tin về công ty X
# 2. Tổng hợp báo cáo tài chính quý gần nhất
# 3. So sánh với đối thủ cạnh tranh
# 4. Viết báo cáo tổng hợp
Phù hợp khi: Task phức tạp, nhiều bước phụ thuộc lẫn nhau, cần nhìn toàn cảnh trước khi hành động (vd: research agent trong capstone).
ReAct (Reasoning + Acting)¶
Xen kẽ giữa suy nghĩ (Thought), hành động (Action), và quan sát (Observation) - mỗi bước phụ thuộc vào kết quả của bước trước, thay vì lập kế hoạch toàn bộ ngay từ đầu.
Thought: Cần biết giá cổ phiếu VNM hôm nay để trả lời câu hỏi.
Action: get_stock_price("VNM")
Observation: VNM: 68,500 VNĐ (+1.2%)
Thought: Đã có giá. Giờ cần biết vốn hoá thị trường để so sánh.
Action: get_market_cap("VNM")
Observation: Vốn hoá: 142,000 tỷ VNĐ
Thought: Đã đủ thông tin để trả lời.
Final Answer: Cổ phiếu VNM hôm nay giao dịch ở mức 68,500 VNĐ (+1.2%)...
from openai import OpenAI
client = OpenAI()
REACT_SYSTEM_PROMPT = """Bạn giải quyết task bằng vòng lặp Thought/Action/Observation.
Sau mỗi Observation, quyết định: cần Action tiếp theo, hay đã đủ để đưa Final Answer.
Không lập kế hoạch trước - suy nghĩ từng bước dựa trên thông tin quan sát được."""
def react_loop(task: str, tools: dict, max_steps: int = 6):
messages = [
{"role": "system", "content": REACT_SYSTEM_PROMPT},
{"role": "user", "content": task},
]
for step in range(max_steps):
response = client.chat.completions.create(
model="gpt-4o-mini", messages=messages, tools=tools["schema"]
)
msg = response.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
result = tools["execute"](call)
messages.append({
"role": "tool", "tool_call_id": call.id, "content": str(result)
})
else:
return msg.content # Final Answer
return "Vượt quá số bước cho phép."
Phù hợp khi: Không biết trước cần bao nhiêu bước hoặc tool nào; mỗi bước phụ thuộc kết quả quan sát trước đó (vd: debug lỗi, multi-hop question answering).
So sánh 3 paradigms¶
| Paradigm | Có bộ nhớ nhiều bước? | Lập kế hoạch trước? | Độ phức tạp task phù hợp |
|---|---|---|---|
| Reflex | Không | Không | Thấp - 1 bước |
| Planning | Có | Có, toàn bộ trước khi chạy | Cao - nhiều bước độc lập, biết trước cấu trúc |
| ReAct | Có | Không, từng bước một | Cao - nhiều bước phụ thuộc kết quả trung gian |
LangGraph hỗ trợ cả 3 paradigm
Bài 2 sẽ dùng LangGraph để implement ReAct loop bằng state graph - đây là paradigm phổ biến nhất cho agent thực tế vì cân bằng giữa tính linh hoạt và khả năng kiểm soát.
5. Landscape 2026¶
Framework so sánh¶
| Framework | Điểm mạnh | Điểm yếu | Dùng khi |
|---|---|---|---|
| LangGraph | Kiểm soát chi tiết state/flow, debug tốt, tích hợp LangSmith | Đường cong học tập cao hơn | Cần custom logic phức tạp, production-grade |
| CrewAI | API cấp cao, dễ setup multi-agent theo "role" | Ít linh hoạt khi cần custom control flow | Prototype nhanh, team-based agents |
| AutoGen | Mạnh về multi-agent conversation, research-oriented | Ít structured hơn cho production | Nghiên cứu, agent hội thoại phức tạp |
| OpenAI Agents SDK | Tích hợp chặt với OpenAI models, đơn giản | Gắn với hệ sinh thái OpenAI | Dự án dùng OpenAI làm nhà cung cấp chính |
Vì sao Module này chọn LangGraph làm mặc định
LangGraph biểu diễn agent như một state graph tường minh - mỗi node, edge, điều kiện rẽ nhánh đều là code bạn kiểm soát hoàn toàn. Điều này giúp debug, test, và mở rộng sang multi-agent dễ dàng hơn so với các framework "hộp đen" cấp cao. Các framework khác sẽ được nhắc đến trong bảng so sánh khi liên quan (Bài 6).
MCP (Model Context Protocol)¶
MCP là chuẩn mở (do Anthropic khởi xướng, nay được nhiều provider hỗ trợ) để kết nối agent với tools/data sources một cách thống nhất - thay vì mỗi tool cần một tích hợp riêng.
graph LR
subgraph "Trước MCP"
A1[Agent A] --> T1[Tool 1 - custom integration]
A1 --> T2[Tool 2 - custom integration]
A2[Agent B] --> T1
A2 --> T2
end
graph LR
subgraph "Với MCP"
AG1[Agent A] --> MCP((MCP Protocol))
AG2[Agent B] --> MCP
MCP --> S1[MCP Server: Filesystem]
MCP --> S2[MCP Server: Database]
MCP --> S3[MCP Server: Vietnamese News]
end
MCP sẽ được đào sâu ở Bài 4 (chuẩn giao tiếp, cách viết Server/Client) - phần này chỉ giới thiệu vị trí của nó trong landscape: MCP giải quyết bài toán N agent × M tool = N×M integration bằng cách chuẩn hoá thành N + M.
Tóm tắt¶
graph TD
Q{Cần xây dựng gì?} --> A[Task 1 bước, input → output cố định]
Q --> B[Task nhiều bước, biết trước cấu trúc]
Q --> C[Task nhiều bước, phụ thuộc kết quả trung gian]
A --> REFLEX[Reflex Agent]
B --> PLANNING[Planning Agent]
C --> REACT[ReAct Agent]
REACT --> FW{Framework?}
PLANNING --> FW
FW --> LG[LangGraph - kiểm soát chi tiết]
FW --> CREW[CrewAI - prototype nhanh]
| Khái niệm | Ghi nhớ |
|---|---|
| Agent vs Pipeline | Ai quyết định bước tiếp theo: code cố định hay LLM? |
| Core components | Brain + Tools + Memory + Planning Loop |
| System prompt | Lắp ráp từ 6 tầng, lọc theo task - không viết 1 khối văn bản |
| AGENTS.md / SOUL.md | Tách "làm gì" (vận hành) khỏi "là ai" (tính cách) |
| Reflex | 1 bước, không nhớ, không lập kế hoạch |
| Planning | Lập kế hoạch toàn bộ trước khi thực thi |
| ReAct | Suy nghĩ - Hành động - Quan sát, lặp lại |
| MCP | Chuẩn hoá kết nối agent ↔ tool, tránh N×M integration |