CodeAgents + Cấu trúc- Một Cách Tốt Hơn để Thực Hiện Hành Động
Đánh giá các tác nhân GUI của bạn một cách dễ dàng!
- 12 min read
CodeAgents + Structure: Một cách tốt hơn để thực hiện các hành động
Hôm nay chúng tôi chia sẻ nghiên cứu kết nối hai mô hình mạnh mẽ trong thiết kế tác nhân AI: tính biểu đạt của các hành động dựa trên mã và độ tin cậy của thế hệ có cấu trúc. Phát hiện của chúng tôi cho thấy rằng việc buộc CodeAgents tạo cả suy nghĩ và mã ở định dạng JSON có cấu trúc có thể vượt trội hơn đáng kể so với các phương pháp truyền thống trên nhiều tiêu chuẩn.
Hình 1: So sánh độ chính xác của ba phương pháp: Structured CodeAgent (màu xanh lam), CodeAgent (màu cam) và ToolCallingAgent (màu xám) trên SmolBench (GAIA, MATH, SimpleQA và Frames). Các thanh lỗi biểu thị Khoảng tin cậy 95%.
🤔 Sự phát triển của các hành động của tác nhân
Các tác nhân AI cần thực hiện các hành động trên thế giới - cho dù đó là gọi API, xử lý dữ liệu hay suy luận các vấn đề phức tạp. Cách các tác nhân thể hiện các hành động này đã phát triển thông qua một số mô hình:
Tác nhân JSON truyền thống: Các tác nhân tạo JSON có cấu trúc để gọi các công cụ.
{
"tool": "get_weather",
"arguments": {
"city": "Paris"
}
}
Các tác nhân này hoạt động bằng cách chọn từ một danh sách các công cụ được xác định trước và tạo các lệnh gọi có định dạng JSON. Phương pháp gọi công cụ này đã được phổ biến bởi API gọi hàm của OpenAI và kể từ đó đã trở thành phương pháp gọi công cụ được sử dụng rộng rãi nhất.
Nó đáng tin cậy, nhưng bị giới hạn bởi:
- Một tập hợp các hành động hạn chế: Các hành động mà tác nhân có thể thực hiện chỉ được thể hiện thông qua các công cụ được xác định trước, điều này hạn chế chức năng của nó.
- Thiếu khả năng kết hợp: Nếu tác vụ yêu cầu kết hợp thông tin từ nhiều nguồn, thì các tác nhân JSON gặp khó khăn vì chúng thiếu hỗ trợ để duy trì trạng thái trung gian trên các lệnh gọi công cụ. Mặc dù một số mô hình hỗ trợ các lệnh gọi công cụ song song, nhưng chúng không thể dễ dàng xử lý các tình huống trong đó đầu ra của một công cụ xác định hành động tiếp theo hoặc nơi cần so sánh và xử lý kết quả cùng nhau.
- Cấu trúc cứng nhắc: Rất hạn chế trong việc xử lý các trường hợp mà các công cụ không khớp chính xác với những gì cần phải làm.
Code Agents: Các tác nhân sử dụng khả năng viết mã vốn có của họ và viết trực tiếp mã Python có thể thực thi.
# We can get the average temperature in 3 cities in 1 model call.
temperature_sum = 0
for city in ["Paris", "Tokyo", "New York"]:
temp = get_weather(city)
temperature_sum += temp
print(f"Average temperature: {temperature_sum / 3:.1f}°C")
Sự thay đổi này, lần đầu tiên được trình bày dưới dạng CodeAct trong bài báo “Hành động mã có thể thực thi khơi gợi các tác nhân LLM tốt hơn”, đã mang lại cho các tác nhân AI sự linh hoạt để viết mã Python có thể thực thi tùy ý ngoài việc gọi công cụ.
Điểm mấu chốt ở đây là các công cụ được gọi trực tiếp từ bên trong mã, giúp cho việc quản lý biến và trạng thái đáng tin cậy hơn nhiều. Các tác nhân có thể gọi các công cụ trong các vòng lặp, hàm và câu lệnh điều kiện - về cơ bản tạo ra một biểu đồ động về việc thực thi công cụ trong mỗi hành động!
Ưu điểm của việc sử dụng CodeAgent:
- Sử dụng công cụ thông minh: Các tác nhân quyết định sử dụng công cụ nào dựa trên những gì đang xảy ra vào thời điểm đó.
- Tính linh hoạt không giới hạn: Có thể sử dụng bất kỳ chức năng Python nào để đạt được mục tiêu.
- Khả năng kiểm tra suy nghĩ: Các tác nhân có thể đưa ra giả thuyết và kiểm tra, dẫn đến sự linh hoạt hơn trong hành động của họ
Tuy nhiên, việc phân tích cú pháp mã từ markdown có thể dễ xảy ra lỗi, điều này dẫn chúng ta đến một đề xuất: tại sao không sử dụng thế hệ có cấu trúc để tạo ra các hành động mã?
➡️ Thêm đầu ra có cấu trúc vào Code Agent
Với đầu ra có cấu trúc, bạn có thể buộc LLM tạo ra các suy nghĩ và mã rõ ràng dưới dạng một blob JSON:
// The "code" block gets parsed into executable Python
{
"thoughts": "I want to find the average temperature across 3 cities.",
"code": "temperature_sum = 0\nfor city in [\"Paris\", \"Tokyo\", \"New York\"]:\n temp = get_weather(city)\n temperature_sum += temp\n\nprint(f\"Average temperature: {temperature_sum / 3:.1f}°C\")"
}
Sự khác biệt chính là thế hệ được thực thi: về cơ bản, bây giờ thay vì chỉ được nhắc đưa ra suy nghĩ, sau đó là mã, việc sử dụng đầu ra có cấu trúc buộc nó phải tôn trọng cấu trúc.
Phương pháp này thêm độ tin cậy của thế hệ có cấu trúc vào tính linh hoạt của việc thực thi mã, do đó có được những điều tốt nhất của cả hai thế giới.
- Lý luận rõ ràng: Trường
thoughtsbuộc tác nhân phải lý luận ngay trước khi thực hiện hành động. - Phân tích cú pháp đáng tin cậy: Cấu trúc JSON loại bỏ các lỗi phân tích cú pháp markdown
- Tính biểu đạt đầy đủ của mã: Trường
codeduy trì tất cả tính linh hoạt của các tác nhân mã - Phân tách tốt hơn: Phân tách rõ ràng giữa lập kế hoạch và thực thi
🧪 Kết quả điểm chuẩn
Chúng tôi đã so sánh ba mô hình này trên nhiều tiêu chuẩn bao gồm GAIA, MATH, SimpleQA và Frames. Kết quả cho thấy một mô hình rõ ràng: Các hành động mã + thế hệ có cấu trúc liên tục cải thiện hiệu suất cho các mô hình có khả năng.
Trên hầu hết các mô hình có khả năng, phương pháp có cấu trúc liên tục vượt trội hơn phương pháp CodeAgent thông thường trung bình từ 2-7 điểm phần trăm.
- Mô hình OpenAI: Cho thấy những cải tiến lớn nhất với cấu trúc, đặc biệt là trên các tác vụ nặng về lý luận
- Mô hình Claude: Hưởng lợi từ cấu trúc, với Claude 3.7 Sonnet cho thấy kết quả đặc biệt mạnh mẽ
- Mô hình Qwen: Nhìn chung được cải thiện với cấu trúc, mặc dù “thuế cấu trúc” (xem trong phần tiếp theo) lẻn vào cho các mô hình nhỏ hơn.
💡 Tại sao cấu trúc (nói chung) giúp
Vấn đề phân tích cú pháp là có thật
Việc triển khai CodeAgent của chúng tôi trong smolagents trích xuất mã Python từ đầu ra LLM, điều này có thể thất bại khi:
- Việc xây dựng khối mã trong markdown không đầy đủ hoặc được định dạng không chính xác
- Nhiều khối mã xuất hiện trong một phản hồi duy nhất
Thế hệ có cấu trúc loại bỏ những vấn đề này với việc phân tích cú pháp JSON đáng tin cậy.
Để hiểu tại sao thế hệ có cấu trúc lại quan trọng, chúng tôi đã phân tích 15.724 dấu vết tác nhân trên các tiêu chuẩn của chúng tôi. Kết quả rất nổi bật:
- 2,4% dấu vết có lỗi phân tích cú pháp trong lần gọi đầu tiên của chúng
- Dấu vết có lỗi phân tích cú pháp lần gọi đầu tiên: Tỷ lệ thành công 42,3%
- Dấu vết không có lỗi phân tích cú pháp lần gọi đầu tiên: Tỷ lệ thành công 51,3%
Dấu vết tác nhân không có lỗi phân tích cú pháp thành công thường xuyên hơn 21,3% so với những dấu vết có lỗi phân tích cú pháp.
Đây không chỉ là về sự tiện lợi - các lỗi phân tích cú pháp tạo ra một loạt các thất bại ảnh hưởng đáng kể đến hiệu suất tổng thể của tác nhân. Khi một tác nhân không thể thực hiện hành động đầu tiên của mình do mã bị lỗi, nó thường gặp khó khăn trong việc phục hồi, dẫn đến các đường dẫn giải quyết vấn đề không tối ưu.
Hình 2: Các lỗi phân tích cú pháp trong bước đầu tiên làm giảm tỷ lệ thành công của tác nhân xuống 21,3% và tăng số bước trung bình thực hiện từ 3,18 lên 4,63.
Ngoài ra: Quá trình suy luận được thực thi
Việc sử dụng thế hệ có cấu trúc và thoughts rõ ràng không chỉ nhắc nhở mà còn buộc các tác nhân phải diễn đạt lý luận của chúng trước khi hành động. Điều này dẫn đến:
- Lập kế hoạch tốt hơn: Các tác nhân suy nghĩ về các vấn đề một cách có hệ thống hơn
- Độ tin cậy nâng cao: Lý luận rõ ràng bắt được các lỗi logic sớm
Thuế cấu trúc
Kết quả của chúng tôi cũng tiết lộ một ngưỡng khả năng rõ ràng: các mô hình cần có đủ khả năng tuân theo hướng dẫn và phạm vi bảo hiểm JSON trong dữ liệu tiền huấn luyện của chúng để hưởng lợi từ thế hệ có cấu trúc. Điều này cho thấy rằng các phương pháp có cấu trúc hoạt động tốt nhất với:
- Các mô hình lớn, được đào tạo tốt
- Các mô hình có khả năng tuân theo hướng dẫn mạnh mẽ
- Các mô hình được tinh chỉnh trên thế hệ có cấu trúc.
Khi cấu trúc bị phá vỡ: Một ví dụ thực tế
Đây là những gì xảy ra khi một mô hình nhỏ hơn (ví dụ: mistralai/Mistral-7B-Instruct-v0.3) cố gắng tạo ra mã có cấu trúc - tải nhận thức trở nên quá lớn:
{
"thought": "I need to find the height...",
"code": "web_search(query=\"Eiffel Tower height\")\", \""
}
Mô hình tạo ra mã Python bị hỏng cú pháp: web_search(query="Eiffel Tower height")", - hãy chú ý đến chuỗi bị lỗi với một dấu ngoặc kép và dấu phẩy thừa. Điều này dẫn đến một SyntaxError và lỗi thực thi ngay lập tức.
Điều này minh họa cho “thuế cấu trúc”: các mô hình nhỏ hơn phải vật lộn để đồng thời xử lý định dạng JSON, cú pháp Python và logic giải quyết vấn đề thực tế. Gánh nặng nhận thức của thế hệ có cấu trúc có thể áp đảo các mô hình mà nếu không sẽ hoạt động khá tốt với thế hệ mã dựa trên markdown đơn giản hơn.
🚀 Khi nào nên sử dụng CodeAgents có cấu trúc
✅ Sử dụng CodeAgents có cấu trúc khi:
- Làm việc với các mô hình có khả năng (tham số 32B+ hoặc các mô hình tiên phong)
- Các nhiệm vụ yêu cầu lý luận và thực thi mã phức tạp
- Bạn cần phân tích cú pháp đầu ra của tác nhân đáng tin cậy
⚠️ Cân nhắc các lựa chọn thay thế khi:
- Làm việc với các mô hình nhỏ hơn phải vật lộn với thế hệ có cấu trúc
- Quy trình làm việc đơn giản, được xác định trước là đủ
Cách sử dụng với smolagents:
Nó siêu đơn giản! Chỉ cần bật nó với use_structured_outputs_internally:
from smolagents import CodeAgent, InferenceClientModel, GoogleSearchTool
# Configure agent for structured generation
agent = CodeAgent(
tools=[GoogleSearchTool(provider="serper")],
model=InferenceClientModel("Qwen/Qwen3-235B-A22B", provider='nebius'),
use_structured_outputs_internally=True # Enable structured output
)
result = agent.run("Calculate the time for a cheetah to run across the Golden Gate Bridge")
LLM sẽ tạo ra một cái gì đó như thế này:
{
"thoughts": "I need to find the length of the Golden Gate Bridge and the top speed of a cheetah, then calculate the time.",
"code": "bridge_info = web_search('Golden Gate Bridge length meters')\ncheetah_speed = web_search('Cheetah top speed') ..."
}
Sau đó, phần “code” được thực thi bởi tác nhân như bình thường: đây là CodeAgent tiêu chuẩn, nhưng bây giờ nó có độ tin cậy phân tích cú pháp 100%!
Lời khuyên thực hiện
- Lời nhắc rõ ràng: Đảm bảo lời nhắc của bạn chỉ định rõ ràng cấu trúc JSON dự kiến
- Lựa chọn mô hình: Chọn các mô hình có khả năng tạo cấu trúc mạnh mẽ
- Chọn nhà cung cấp phù hợp: Một số nhà cung cấp API như OpenAI hoặc Anthropic hỗ trợ tạo cấu trúc ngay lập tức. Nếu bạn đang sử dụng các nhà cung cấp Inference thông qua Hugging Face, thì sự hỗ trợ của tạo cấu trúc khác nhau giữa các nhà cung cấp. Dưới đây là danh sách các nhà cung cấp hỗ trợ tạo cấu trúc: Hỗ trợ tạo cấu trúc cho Mô hình trong smolagents‣
Bức tranh lớn hơn - Điều gì tiếp theo?
Nghiên cứu này cho thấy chúng ta đang tiến tới một sự hiểu biết sắc thái hơn về kiến trúc tác nhân. Nó không chỉ là “tác nhân có thể làm gì?” mà là “tác nhân nên suy nghĩ như thế nào về những gì nó đang làm?”
Có lẽ làm cho quá trình lý luận rõ ràng hơn sẽ giúp mô hình đi đúng hướng. Hoặc có lẽ chỉ là dễ phân tích cú pháp hơn. Dù bằng cách nào, đó là một chiến thắng.
Nhưng đây chỉ là sự khởi đầu. Có rất nhiều câu hỏi còn lại để khám phá:
- Những cải tiến cấu trúc nào khác có thể giúp ích?
- Làm thế nào chúng ta làm cho điều này hoạt động tốt hơn trên các kiến trúc mô hình khác nhau, đặc biệt là các mô hình smol?
- Điều này cho chúng ta biết gì về bản chất của lý luận AI?
Hiện tại, nếu bạn đang sử dụng smolagents (hoặc xây dựng hệ thống CodeAgent của riêng bạn), hãy cân nhắc dùng thử đầu ra có cấu trúc. Các lỗi phân tích cú pháp của bạn sẽ cảm ơn bạn và bạn có thể chỉ thấy một sự gia tăng hiệu suất tốt!
Link bài viết gốc
- Tags:
- Ai
- May 28, 2025
- Huggingface.co