Giờ ta ghép hai nửa lại: một agent (MCP client) tự động khám phá tool từ server, để model chọn tool, thực thi, và trả lời người dùng. Đây là vòng lặp agentic hoàn chỉnh.
Bức tranh tổng thể
Người dùng hỏi
→ Host gửi câu hỏi + danh sách tool (từ tools/list) cho LLM
→ LLM quyết định: gọi tool nào, tham số gì (tool call)
→ Client thực thi tools/call qua server
→ Server trả kết quả
→ Kết quả đưa lại LLM
→ LLM tạo câu trả lời cuối (hoặc gọi tiếp tool)
Vòng lặp "LLM → tool → kết quả → LLM" có thể lặp nhiều lần cho tới khi model đủ thông tin để trả lời.
Bước 1 — Client kết nối và khám phá
Dùng SDK client (pseudocode):
session = await connect_stdio("python", ["weather_server.py"])
await session.initialize() # handshake
tools = await session.list_tools() # khám phá
Bước 2 — Chuyển tool MCP thành "tool schema" cho LLM
Mỗi tool MCP có name, description, inputSchema. Bạn map chúng sang định dạng tool-use của model:
llm_tools = [{
"name": t.name,
"description": t.description,
"input_schema": t.inputSchema
} for t in tools]
Bước 3 — Vòng lặp agent
messages = [{"role": "user", "content": cau_hoi}]
while True:
resp = llm.create(messages=messages, tools=llm_tools)
if resp.stop_reason == "tool_use":
for call in resp.tool_calls:
result = await session.call_tool(call.name, call.args)
messages.append(tool_result(call.id, result))
else:
return resp.text # câu trả lời cuối
Điểm mấu chốt: model chọn tool, client chỉ thực thi và đưa kết quả lại. Client là cầu nối, không phải bộ não.
Bước 4 — Nhiều server cùng lúc
Agent thực tế nối nhiều server: orders, email, docs. Bạn gộp tool từ tất cả vào một danh sách cho LLM. Khi model gọi send_email, client định tuyến tới đúng server email.
> Khung tư duy định tuyến: giữ một bảng tool_name → session. Khi model gọi tool, tra bảng để biết gửi tới server nào. Đặt tên tool có tiền tố (orders_query, email_send) để tránh trùng khi nhiều server có tool cùng tên.
Ví dụ luồng thật
Người dùng: "Đơn của khách 0909... bị lỗi, gửi email xin lỗi giúp."
- LLM gọi
orders_query(phone)→ lấy đơn #4821, thấy lỗi giao hàng. - LLM gọi
email_send(to, subject, body)với nội dung xin lỗi. - LLM trả lời: "Đã gửi email xin lỗi cho khách về đơn #4821."
email_send nên có bước xác nhận (bài 6).Xử lý nhiều tool call và giới hạn vòng lặp
Trong một lượt, model có thể phát ra nhiều tool call cùng lúc (ví dụ tra 3 đơn song song). Client nên thực thi tất cả và gộp kết quả trả lại trước khi gọi model lần nữa — đừng chỉ xử lý cái đầu tiên. Ngoài ra, vòng lặp "model → tool → model" cần một trần số vòng (ví dụ tối đa 8 vòng). Không có trần, một model bối rối có thể gọi tool lặp vô tận, đốt token và tiền. Khi chạm trần, hãy dừng và trả một câu trả lời an toàn ("Tôi chưa đủ thông tin, bạn bổ sung giúp...").
MAX_TURNS = 8
for _ in range(MAX_TURNS):
resp = llm.create(messages=messages, tools=llm_tools)
if resp.stop_reason != "tool_use":
return resp.text
for call in resp.tool_calls:
try:
result = await route(call.name).call_tool(call.name, call.args)
except Exception as e:
result = f"Lỗi khi gọi {call.name}: {e}"
messages.append(tool_result(call.id, result))
return "Đã đạt giới hạn số bước xử lý."
Chú ý khối try/except: lỗi tool được bắt và trả lại model dưới dạng text, để model tự xử lý (thử cách khác hoặc báo người dùng) thay vì làm sập cả vòng lặp. Đây là khác biệt giữa một agent giòn và một agent bền.
Checklist tích hợp end-to-end
- [ ] Client hoàn tất
initializetrước khi gọi tool. - [ ] Tool schema (đặc biệt
inputSchema) được map đầy đủ cho LLM. - [ ] Vòng lặp xử lý được nhiều tool call trong một lượt.
- [ ] Kết quả tool (kể cả lỗi) được đưa lại LLM đúng định dạng.
- [ ] Định tuyến đúng tool → đúng server khi có nhiều server.
- [ ] Có giới hạn số vòng lặp để tránh loop vô hạn.
Sai lầm thường gặp
- Không đưa kết quả tool lại cho model → model không biết tool đã chạy, trả lời sai hoặc gọi lại.
- Quên map
inputSchema→ model đoán tham số, gọi tool với đối số sai. - Không giới hạn vòng lặp → agent kẹt gọi tool liên tục, tốn token/tiền.
- Trùng tên tool giữa các server mà không có tiền tố → định tuyến sai.
- Nuốt lỗi tool thay vì trả lại cho model → model không thể tự sửa hay báo người dùng.