Trong một bài đăng trên blog của Machine Learning Mastery, tác giả Jason Brownlee đã định nghĩa học sâu (deep learning) là một nhánh của học máy (machine learning) dựa trên mạng nơ-ron nhân tạo (artificial neural networks). Các thuật toán học sâu sử dụng nhiều lớp để trích xuất các đặc trưng cấp cao hơn từ dữ liệu đầu vào. Ví dụ, trong xử lý hình ảnh, các lớp đầu tiên có thể phát hiện các cạnh hoặc góc, trong khi các lớp sâu hơn có thể nhận diện các đối tượng phức tạp hơn như khuôn mặt hoặc xe cộ.
Học sâu đã đạt được những thành công đáng kể trong nhiều lĩnh vực, bao gồm thị giác máy tính (computer vision), xử lý ngôn ngữ tự nhiên (natural language processing) và nhận dạng giọng nói (speech recognition). Một trong những lý do chính cho sự thành công này là khả năng học hỏi từ lượng lớn dữ liệu mà không cần kỹ thuật đặc trưng thủ công (manual feature engineering). Điều này đã mở ra những khả năng mới cho trí tuệ nhân tạo (AI) và dẫn đến sự phát triển của các ứng dụng đột phá như xe tự lái, trợ lý ảo và hệ thống đề xuất.
Xây dựng tác nhân Gemma 4 đa công cụ có khả năng phục hồi lỗi
Ngày 22/5/2026
Chia sẻ
Trong bài viết này, độc giả sẽ tìm hiểu cách biến một tập lệnh gọi công cụ cơ bản thành một tác nhân có khả năng phục hồi, xử lý linh hoạt các lỗi phát sinh từ công cụ hoạt động sai, đầu ra mô hình không đúng định dạng và dịch vụ không khả dụng.
Các chủ đề sẽ được đề cập bao gồm:
Cách cấu trúc một vòng lặp tác nhân lặp lại với giới hạn an toàn về số lần lặp.
Bốn loại lỗi riêng biệt mà một tác nhân gặp phải khi gọi công cụ và cách xử lý từng loại.
Cách thiết kế thông báo lỗi công cụ nhằm hướng dẫn mô hình cách phục hồi, giảm thiểu các lần lặp lãng phí.
Xây dựng tác nhân Gemma 4 đa công cụ có khả năng phục hồi lỗi
Giới thiệu
Trong một bài viết trước, chúng tôi đã kết nối Gemma 4 với một số hàm Python bằng API gọi công cụ của Ollama. Điều này cung cấp cho chúng tôi một bộ điều phối một lượt hoạt động: mô hình chọn một công cụ, mã của chúng tôi chạy công cụ đó, mô hình trả lời. Đây là một điểm khởi đầu hữu ích, nhưng còn rất xa so với một tác nhân hoàn chỉnh.
Một trong những yếu tố biến bản trình diễn gọi công cụ thành một tác nhân thực sự là cách nó xử lý các sự cố. Các công cụ có thể gặp lỗi. Mô hình có thể tạo ra một tên hàm không tồn tại, hoặc truyền một chuỗi thay vì một số, hoặc hỏi về một thành phố mà bảng tra cứu của bạn chưa từng nghe đến. Một API thượng nguồn có thể hết thời gian chờ. Một đối số bắt buộc có thể bị thiếu. Trong hướng dẫn trước, bất kỳ trường hợp nào trong số này đều có thể làm sập tập lệnh hoặc bị nuốt bởi một khối try/except (thử/ngoại lệ) in ra thông báo và từ bỏ. Điều đó ổn cho một bản trình diễn đơn lẻ. Nhưng không ổn cho bất kỳ thứ gì bạn muốn duy trì hoạt động.
Bài viết này xây dựng lại tác nhân dựa trên giả định rằng mọi thứ sẽ gặp trục trặc và chỉ ra cách phục hồi một cách linh hoạt khi chúng xảy ra. Mô hình rất đơn giản: bắt lỗi tại ranh giới, chuyển đổi chúng thành các thông báo mà mô hình có thể đọc, gửi chúng trở lại mô hình và để mô hình quyết định có nên thử lại, giải quyết vấn đề bằng cách khác hay giải thích lỗi cho người dùng. Chúng tôi cũng sẽ gói gọn mọi thứ trong một vòng lặp tác nhân lặp lại phù hợp với giới hạn an toàn về số lần lặp.
Toàn bộ tập lệnh có thể được tìm thấy tại đây. Bài viết này sẽ đi sâu vào các phần quan trọng.
Suy nghĩ lại về vòng lặp công cụ
Bộ điều phối ban đầu chạy một vòng duy nhất: gửi truy vấn của người dùng, thu thập các lệnh gọi công cụ, chạy chúng, gửi kết quả trở lại, in phản hồi của mô hình. Đó là một tương tác một lần. Nó hoạt động tốt khi phản hồi đầu tiên của mô hình trả lời đúng câu hỏi của người dùng, nhưng nó không có cách nào để xử lý khi có sự cố. Nếu một công cụ gặp lỗi, mô hình có một cơ hội để phản ứng và sau đó chúng ta kết thúc. Nếu mô hình muốn gọi một công cụ khác sau khi xem kết quả đầu tiên, thì không thể; chúng ta đã thoát.
Một vòng lặp tác nhân phù hợp là lặp đi lặp lại. Cấu trúc rất đơn giản:
Gửi lịch sử tin nhắn hiện tại đến mô hình.
Nếu mô hình tạo ra các lệnh gọi công cụ, hãy thực thi từng lệnh, thêm mọi kết quả vào lịch sử và lặp lại.
Nếu mô hình tạo ra một phản hồi văn bản thuần túy, đó là câu trả lời cuối cùng. Trả về.
Giới hạn vòng lặp ở MAX_ITERATIONS (số lần lặp tối đa) để một mô hình bị nhầm lẫn không thể tiêu tốn CPU của bạn mãi mãi.
Điểm cuối cùng đó là không thể thương lượng. Các mô hình nhỏ đôi khi bị kẹt khi gọi cùng một công cụ lặp đi lặp lại, hoặc dao động giữa hai công cụ, và không có gì đáng nản hơn khi quay lại thiết bị đầu cuối của bạn và thấy quạt máy tính xách tay của bạn đang kêu gào vì Gemma đã quyết định tra cứu thời tiết ở London ba mươi lần liên tiếp.
Đây là vòng lặp:
def run_agent(user_query):
messages = [{"role": "user", "content": user_query}]
for iteration in range(1, MAX_ITERATIONS + 1):
payload = {
"model": MODEL_NAME,
"messages": messages,
"tools": available_tools,
"stream": False,
}
print(f"[EXECUTION — iteration {iteration}]")
print(" ● Querying model...\n")
try:
response_data = call_ollama(payload)
except Exception as e:
print(f" └─ [ERROR] Error calling Ollama API: {e}")
print(f" └─ Make sure Ollama is running and {MODEL_NAME} is pulled.")
return
message = response_data.get("message", {})
tool_calls = message.get("tool_calls") or []
# Branch A: the model wants to use tools
if tool_calls:
print(f"[TOOL EXECUTION — {len(tool_calls)} call(s)]")
messages.append(message)
tool_messages = print_tool_calls(tool_calls)
messages.extend(tool_messages)
print()
continue
# Branch B: the model produced a final answer
print("[RESPONSE]")
print(message.get("content", "") + "\n")
return
# Safety rail: we exhausted MAX_ITERATIONS without a final answer
print("[RESPONSE]")
print(
f"Hit the {MAX_ITERATIONS}-iteration cap without a final answer. "
"This usually means the model is stuck in a tool-calling loop. "
"Try simplifying the query.\n"
)
Nguồn tin: Machine Learning Mastery — Tác giả: Matthew Mayo. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.