Bài 2 dừng ở chỗ LLM yêu cầu gọi tool. Bài này ta thực thi tool, trả kết quả về, và lặp — biến một lời gọi API thành agent thật sự.
Bước 1: Viết bộ điều phối (dispatcher)
Dispatcher ánh xạ tên tool → hàm Python thật:
def read_file(path):
with open(path, "r", encoding="utf-8") as f:
return f.read()
def run_command(command):
import subprocess
r = subprocess.run(command, shell=True, capture_output=True,
text=True, timeout=60)
return f"exit={r.returncode}\nSTDOUT:\n{r.stdout}\nSTDERR:\n{r.stderr}"
TOOL_FUNCS = {"read_file": read_file, "run_command": run_command}
def run_tool(name, args):
try:
return TOOL_FUNCS[name](**args)
except Exception as e:
return f"ERROR: {type(e).__name__}: {e}" # trả lỗi, KHÔNG raise
Chú ý dòng cuối: khi tool lỗi, ta trả chuỗi lỗi cho LLM thay vì để chương trình crash. Đây là mấu chốt của vòng lặp tự sửa: LLM cần đọc được lỗi để phản ứng.
Bước 2: Vòng lặp hoàn chỉnh
messages = [{"role": "user", "content": user_task}]
for step in range(25): # giới hạn 25 vòng
resp = client.messages.create(
model=MODEL, max_tokens=2048,
tools=TOOLS, messages=messages)
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason != "tool_use":
print(final_text(resp)); break # xong
results = []
for block in resp.content:
if block.type == "tool_use":
out = run_tool(block.name, block.input)
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": out,
})
messages.append({"role": "user", "content": results})
else:
print("Đã đạt giới hạn vòng lặp — dừng an toàn.")
Bước 3: Hiểu "khớp ID" của tool result
Mỗi tool_use block có id. Khi trả kết quả, bạn phải gắn đúng tool_use_id tương ứng. Nếu LLM gọi 3 tool cùng lúc, bạn trả về 3 tool_result khớp 3 id. Sai id ⇒ API báo lỗi hoặc LLM hiểu nhầm kết quả thuộc về tool nào.
Ví dụ chạy thực
Task: "Có bao nhiêu dòng trong app.py?"
- Vòng 1 — LLM gọi
run_command("wc -l app.py"). - Agent chạy → trả
exit=0\nSTDOUT:\n42 app.py. - Vòng 2 — LLM đọc kết quả, không gọi tool nữa, trả lời "File có 42 dòng." →
break.
Khung tư duy: 3 bất biến của vòng lặp
- Mọi assistant message đều được append trước khi xử lý tool — để history nhất quán.
- Mọi tool_use đều sinh đúng một tool_result khớp id — không thiếu, không thừa.
- Luôn có lối thoát: điều kiện dừng (không tool) và trần vòng lặp (max steps).
Checklist
- [ ] Dispatcher bắt exception và trả chuỗi lỗi, không raise.
- [ ] Tool result gắn đúng
tool_use_id. - [ ] Có
max_stepsvà nhánh xử lý khi chạm trần. - [ ] Append cả assistant message lẫn tool result vào history.
- [ ]
run_commandcótimeoutđể tránh treo vô hạn.
Sai lầm thường gặp
- Để tool raise exception làm sập agent. Một lệnh sai cú pháp không nên giết cả phiên; hãy trả lỗi cho LLM xử lý.
- Trả thiếu tool_result khi LLM gọi nhiều tool song song. API sẽ từ chối message tiếp theo.
- Không append assistant content chứa tool_use trước khi gửi tool_result — phá vỡ thứ tự hội thoại.
- Quên timeout ở run_command. Một lệnh
npm installhoặc server chạy nền có thể treo agent mãi mãi. - Đặt max_steps quá thấp (2–3). Task thật thường cần 8–15 vòng; trần quá thấp khiến agent bỏ dở.
Học xong bài này rồi?
Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu,
và học hết khóa thì có chứng chỉ.
Lưu tiến độ của tôi