Bỏ qua tới nội dung
Bài 11/12 · Khoá học AI Agent (Hugging Face)

Tạo agent đầu tiên với smolagents

Nhân bản Space mẫu, thêm HF_TOKEN, tìm hiểu tool, CodeAgent và system prompt trong app.py để xây agent đầu tiên bằng smolagents.

Cơ bản@shine19047 phút đọc

Ở bài trước, chúng ta đã học cách tạo agent từ đầu bằng code Python và thấy rõ quá trình đó có thể tẻ nhạt đến mức nào. May mắn là nhiều thư viện agent đơn giản hoá công việc này bằng cách đảm nhận phần lớn việc nặng nhọc giúp bạn.

Trong bài hướng dẫn này, bạn sẽ tạo agent đầu tiên của mình, có thể thực hiện các hành động như tạo ảnh, tìm kiếm web, xem múi giờ và nhiều hơn nữa!

Bạn cũng sẽ công bố agent lên một Hugging Face Space để chia sẻ với bạn bè và đồng nghiệp.

Bắt đầu thôi!

smolagents là gì?

smolagents

Để tạo agent này, chúng ta sẽ dùng smolagents, một thư viện cung cấp framework giúp phát triển agent dễ dàng.

Thư viện gọn nhẹ này được thiết kế để đơn giản, nhưng nó che đi phần lớn độ phức tạp khi xây agent, để bạn tập trung thiết kế hành vi của agent.

Chúng ta sẽ đi sâu hơn vào smolagents ở unit sau. Trong lúc chờ, bạn có thể xem bài blog này hoặc repo GitHub của thư viện.

Nói ngắn gọn, smolagents là thư viện tập trung vào codeAgent, một loại agent thực hiện "Action" qua các khối code, rồi "Observe" kết quả bằng cách thực thi code đó.

Đây là ví dụ về thứ chúng ta sẽ xây!

Chúng ta trao cho agent một tool tạo ảnh và yêu cầu nó tạo ảnh một con mèo.

Agent trong smolagents sẽ có cùng hành vi với agent tự dựng mà chúng ta đã xây trước đó: nó sẽ suy nghĩ, hành động và quan sát theo chu trình cho đến khi đạt câu trả lời cuối cùng. Xem video minh hoạ trên YouTube.

Thú vị phải không?

Cùng xây agent!

Để bắt đầu, hãy nhân bản (duplicate) Space này: https://huggingface.co/spaces/agents-course/First_agent_template

Cảm ơn Aymeric vì template này!

Nhân bản Space nghĩa là tạo một bản sao trên profile của chính bạn:

Nhân bản Space

Sau khi nhân bản Space, bạn cần thêm token API của Hugging Face để agent truy cập được API của model:

  1. Trước hết, lấy token Hugging Face tại https://hf.co/settings/tokens với quyền inference, nếu bạn chưa có
  2. Vào Space đã nhân bản và bấm tab Settings
  3. Cuộn xuống mục Variables and Secrets và bấm New Secret
  4. Tạo một secret tên HF_TOKEN và dán token của bạn vào làm giá trị
  5. Bấm Save để lưu token an toàn

Trong suốt bài này, file duy nhất bạn cần sửa là "app.py" (hiện chưa hoàn chỉnh). Bạn có thể xem bản gốc trong template. Để tìm bản của bạn, vào bản sao của Space, bấm tab Files rồi bấm app.py trong danh sách thư mục.

Chúng ta cùng phân tích code:

  • File bắt đầu bằng vài lệnh import thư viện đơn giản nhưng cần thiết
python
from smolagents import CodeAgent, DuckDuckGoSearchTool, FinalAnswerTool, InferenceClientModel, load_tool, tool
import datetime
import requests
import pytz
import yaml

Như đã nói ở trên, chúng ta sẽ dùng trực tiếp class CodeAgent của smolagents.

Các tool

Giờ đến phần tool! Nếu cần ôn lại về tool, đừng ngại quay lại bài Tool của khoá học.

python
@tool
def my_custom_tool(arg1:str, arg2:int)-> str: # it's important to specify the return type
    # Keep this format for the tool description / args description but feel free to modify the tool
    """A tool that does nothing yet 
    Args:
        arg1: the first argument
        arg2: the second argument
    """
    return "What magic will you build ?"

@tool
def get_current_time_in_timezone(timezone: str) -> str:
    """A tool that fetches the current local time in a specified timezone.
    Args:
        timezone: A string representing a valid timezone (e.g., 'America/New_York').
    """
    try:
        # Create timezone object
        tz = pytz.timezone(timezone)
        # Get current time in that timezone
        local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
        return f"The current local time in {timezone} is: {local_time}"
    except Exception as e:
        return f"Error fetching time for timezone '{timezone}': {str(e)}"

Tool chính là thứ chúng tôi khuyến khích bạn tự xây trong phần này! Có sẵn hai ví dụ:

  1. Một tool giả lập chưa hoạt động mà bạn có thể sửa để làm thành thứ hữu ích.
  2. Một tool hoạt động thật, lấy giờ hiện tại ở một nơi trên thế giới.

Để định nghĩa tool, điều quan trọng là:

  1. Khai báo kiểu đầu vào và đầu ra cho hàm, như trong get_current_time_in_timezone(timezone: str) -> str:
  2. Một docstring được định dạng tốt. smolagents yêu cầu mọi đối số đều có mô tả bằng văn bản trong docstring.

Agent

Agent dùng Qwen/Qwen2.5-Coder-32B-Instruct làm LLM. Đây là một model rất mạnh mà chúng ta sẽ truy cập qua serverless API.

python
final_answer = FinalAnswerTool()
model = InferenceClientModel(
    max_tokens=2096,
    temperature=0.5,
    model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
    custom_role_conversions=None,
)

with open("prompts.yaml", 'r') as stream:
    prompt_templates = yaml.safe_load(stream)
    
# We're creating our CodeAgent
agent = CodeAgent(
    model=model,
    tools=[final_answer], # add your tools here (don't remove final_answer)
    max_steps=6,
    verbosity_level=1,
    grammar=None,
    planning_interval=None,
    name=None,
    description=None,
    prompt_templates=prompt_templates
)

GradioUI(agent).launch()

Agent này vẫn dùng InferenceClient mà chúng ta đã thấy ở bài trước, nằm phía sau class InferenceClientModel!

Chúng ta sẽ có các ví dụ chuyên sâu hơn khi giới thiệu framework ở unit 2. Hiện tại, bạn cần tập trung vào việc thêm tool mới vào danh sách tool qua tham số tools của agent.

Ví dụ, bạn có thể dùng DuckDuckGoSearchTool đã được import ở dòng đầu tiên, hoặc xem image_generation_tool được nạp từ Hub ở phần sau của code.

Thêm tool sẽ trao cho agent những khả năng mới, hãy sáng tạo nhé!

System prompt

System prompt của agent được lưu trong một file riêng là prompts.yaml. File này chứa các chỉ dẫn định sẵn, định hướng hành vi của agent.

Lưu prompt trong file YAML giúp dễ tuỳ chỉnh và tái sử dụng cho nhiều agent hoặc nhiều trường hợp sử dụng khác nhau.

Bạn có thể xem cấu trúc file của Space để biết file prompts.yaml nằm ở đâu và được tổ chức thế nào trong dự án.

File "app.py" hoàn chỉnh:

python
from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel, load_tool, tool
import datetime
import requests
import pytz
import yaml
from tools.final_answer import FinalAnswerTool

from Gradio_UI import GradioUI

# Below is an example of a tool that does nothing. Amaze us with your creativity!
@tool
def my_custom_tool(arg1:str, arg2:int)-> str: # it's important to specify the return type
    # Keep this format for the tool description / args description but feel free to modify the tool
    """A tool that does nothing yet 
    Args:
        arg1: the first argument
        arg2: the second argument
    """
    return "What magic will you build ?"

@tool
def get_current_time_in_timezone(timezone: str) -> str:
    """A tool that fetches the current local time in a specified timezone.
    Args:
        timezone: A string representing a valid timezone (e.g., 'America/New_York').
    """
    try:
        # Create timezone object
        tz = pytz.timezone(timezone)
        # Get current time in that timezone
        local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
        return f"The current local time in {timezone} is: {local_time}"
    except Exception as e:
        return f"Error fetching time for timezone '{timezone}': {str(e)}"


final_answer = FinalAnswerTool()
model = InferenceClientModel(
    max_tokens=2096,
    temperature=0.5,
    model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
    custom_role_conversions=None,
)


# Import tool from Hub
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)

# Load system prompt from prompt.yaml file
with open("prompts.yaml", 'r') as stream:
    prompt_templates = yaml.safe_load(stream)
    
agent = CodeAgent(
    model=model,
    tools=[final_answer], # add your tools here (don't remove final_answer)
    max_steps=6,
    verbosity_level=1,
    grammar=None,
    planning_interval=None,
    name=None,
    description=None,
    prompt_templates=prompt_templates # Pass system prompt to CodeAgent
)


GradioUI(agent).launch()

Mục tiêu của bạn là làm quen với Space và agent.

Hiện tại, agent trong template chưa dùng tool nào, nên hãy thử trao cho nó vài tool dựng sẵn, hoặc tự làm tool mới!

Tổng kết

Chúc mừng, bạn đã xây agent đầu tiên của mình! Đừng ngại chia sẻ nó với bạn bè và đồng nghiệp.

Vì đây là lần thử đầu tiên, việc agent hơi lỗi hoặc chậm là hoàn toàn bình thường. Ở các unit sau, chúng ta sẽ học cách xây những agent tốt hơn nữa.

Cách học tốt nhất là thử, nên đừng ngại cập nhật agent, thêm tool, thử model khác…

Nguồn