Hệ thống Hook trong AgentScope

Hệ thống Hook của AgentScope là cơ chế mở rộng phi xâm nhập cốt lõi, cho phép chèn logic tùy chỉnh vào các mốc quan trọng trong vòng đời thực thi agent để thực hiện ghi log, giám sát, bảo mật, sửa đổi, kiểm toán và cập nhật nóng.

1. Tư tưởng thiết kế

  • Phi xâm nhập: Không thay đổi mã nguồn cốt lõi
  • Mẫu thiết kế chuỗi trách nhiệm: Nhiều hook thực thi theo thứ tự
  • Intercept hai chiều: pre_* (trước), post_* (sau)
  • Chỉnh sửa ngữ cảnh: pre có thể sửa đầu vào, post có thể sửa đầu ra
  • Hai cấp độ phạm vi: Cấp lớp (toàn cục), Cấp thể hiện (đối tượng đơn lẻ)

2. Thứ tự thực thi

Khi cùng sự kiện kích hoạt:
1. Thực thi tất cả hook cấp lớp
2. Sau đó thực thi hook cấp thể hiện
3. Cấp độ cùng loại theo thứ tự đăng ký

3. Chữ ký hàm hook (Python)

(1) Hook trước pre_*

def pre_hook(
    tự: AgentBase,    # Agent hiện tại
    tham_so: dict     # Tất cả tham số đầu vào
) -> dict | None:    # Trả về tham_so mới, None = không thay đổi

(2) Hook sau post_*

def post_hook(
    tự: AgentBase,    # Agent hiện tại
    tham_so: dict,    # Tham số đầu vào
    ket_qua: Any      # Giá trị trả về gốc
) -> Any | None:     # Trả về kết quả mới, None = không thay đổi

Danh sách đầy đủ loại hook (theo Agent)

1. AgentBase (Agent cơ bản)

  • pre_reply / post_reply: Trước/sau khi trả lời (thường dùng nhất)
  • pre_observe / post_observe: Trước/sau khi quan sát (nhận tin nhắn bên ngoài)
  • pre_print / post_print: Trước/sau khi in

2. ReActAgentBase (Agent suy luận-hành động, thường dùng)

Kế thừa từ AgentBase, thêm:

  • pre_reasoning / post_reasoning: Trước/sau khi suy luận LLM
  • pre_acting / post_acting: Trước/sau khi gọi công cụ

3. Chuỗi kích hoạt đầy đủ (ReAct)

Đầu vào người dùng
→ pre_observe
→ observe
→ post_observe
→ pre_reply
  → pre_reasoning
  → _reasoning (suy luận LLM)
  → post_reasoning
  → pre_acting
  → _acting (gọi công cụ)
  → post_acting
→ reply (kết quả trả về)
→ post_reply
→ pre_print
→ print
→ post_print

Quản lý hook (API)

1. Hook cấp thể hiện (Agent đơn lẻ)

# Đăng ký
agent.dang_ky_hook_the_hien(
    loai_hook: str,   # VD: "pre_reply"
    ten: str,         # Tên hook (dùng để xóa)
    hook: Callable    # Hàm hook
)

# Xóa
agent.xoa_hook_the_hien(
    loai_hook: str,
    ten: str
)

2. Hook cấp lớp (Tất cả Agent cùng lớp)

# Đăng ký
ReActAgent.dang_ky_hook_lop(
    loai_hook: str,
    ten: str,
    hook: Callable
)

# Xóa
ReActAgent.xoa_hook_lop(
    loai_hook: str,
    ten: str
)

5 ví dụ điển hình

Ví dụ 1: Ghi log (pre_reply + post_reply)

from agentscope.agents import ReActAgent
import json
import time

def ghi_nhap_yeu_cau(tự, tham_so):
    """Ghi log yêu cầu"""
    print(f"[LOG] {tự.ten} nhận yêu cầu: {tham_so['msg']}")
    return tham_so

def ghi_ket_qua(tự, tham_so, ket_qua):
    """Ghi log phản hồi"""
    print(f"[LOG] {tự.ten} trả lời: {ket_qua}")
    return ket_qua

# Tạo Agent
bot = ReActAgent(
    ten="Trợ lý",
    sys_prompt="Bạn là trợ lý hữu ích"
)

# Đăng ký hook thể hiện
bot.dang_ky_hook_the_hien("pre_reply", "log_req", ghi_nhap_yeu_cau)
bot.dang_ky_hook_the_hien("post_reply", "log_resp", ghi_ket_qua)

# Kiểm tra
bot.chay("Chào bạn")

Ví dụ 2: Kiểm duyệt an toàn (pre_reasoning)

def kiem_tra_an_toan(tự, tham_so):
    cau_hoi = tham_so.get("prompt", "")
    if "bom" in cau_hoi:
        tham_so["prompt"] = "Bạn không được thảo luận nội dung nguy hiểm"
    return tham_so

Ví dụ 3: Giám sát công cụ (pre_acting)

def giam_sat_cong_cu(tự, tham_so):
    ten_cong_cu = tham_so.get("tool_name")
    tham_so_cong_cu = tham_so.get("tool_args", {})
    print(f"[Giám sát] {tự.ten} gọi công cụ: {ten_cong_cu}, tham số: {tham_so_cong_cu}")
    if ten_cong_cu == "xoa_tep":
        tham_so["tool_args"] = {}
    return tham_so

Ví dụ 4: Hook toàn cục (tất cả Agent)

def log_toan_cuc(tự, tham_so):
    print(f"[Toàn cục] {tự.ten} xử lý: {tham_so}")
    return tham_so

ReActAgent.dang_ky_hook_lop("pre_reply", "log_toan_cuc", log_toan_cuc)
bot1 = ReActAgent(ten="A")
bot2 = ReActAgent(ten="B")

Ví dụ 5: Xử lý lỗi (on_error)

def xu_ly_loi(tự, tham_so, loi):
    print(f"[Lỗi] {tự.ten} xảy ra lỗi: {loi}")
    return "Xin lỗi, dịch vụ tạm thời không sử dụng được"

Ứng dụng cao cấp

1. Nhúng kỹ năng động (pre_reasoning)

def nhap_ky_nang(tự, tham_so):
    cau_hoi = tham_so["prompt"]
    from agentscope.ky_nang import Phan_Tich_Ky_Nang
    danh_sach_ky_nang = Phan_Tich_Ky_Nang.phu_hop(cau_hoi)
    noi_dung_ky_nang = "\n".join([k.noi_dung for k in danh_sach_ky_nang])
    tham_so["prompt"] = f"{noi_dung_ky_nang}\nCâu hỏi: {cau_hoi}"
    return tham_so

2. Cập nhật Nacos nóng (post_reply)

def cap_nhat_nacos(tự, tham_so, ket_qua):
    from agentscope.ky_nang import Nguon_Ky_Nang_Nacos
    nguon_nacos = Nguon_Ky_Nang_Nacos(...)
    if nguon_nacos.co_cap_nhat():
        tự.ky_nang = nguon_nacos.doc_tat_ca()
        print("[Cập nhật] Đã cập nhật kỹ năng")
    return ket_qua

3. Thực thi chuỗi hook

bot.dang_ky_hook_the_hien("pre_reasoning", "ghi_log", hook_ghi_log)
bot.dang_ky_hook_the_hien("pre_reasoning", "kiem_tra", hook_kiem_tra)
bot.dang_ky_hook_the_hien("pre_reasoning", "nhap_ky_nang", hook_nhap_ky_nang)

Thực hành tốt nhất

  1. Trường hợp đơn giản: Dùng hook thể hiện (linh hoạt, cách ly)
  2. Logic toàn cục: Dùng hook cấp lớp (log, giám sát, kiểm toán)
  3. Hiệu năng: Tránh thao tác tốn thời gian trong hook (xử lý bất đồng bộ)
  4. Độ ổn định: Bắt lỗi trong hook, tránh agent crash
  5. Đặt tên: modun_chức_năng (VD: ghi_log, kiem_tra_an_toan)
  6. Gỡ lỗi: Dùng verbose=True để xem trình tự hook

Tổng kết

Hệ thống Hook AgentScope = Middleware của Agent

  • pre_*: Sửa đầu vào, kiểm tra an ninh, nhúng kiến thức
  • post_*: Sửa kết quả, báo cáo log, kích hoạt cập nhật nóng
  • Hai cấp phạm vi: Toàn cục + tùy chỉnh thể hiện
  • Bao phủ toàn vòng đời: Từ đầu vào → quan sát → suy luận → hành động → đầu ra

Thẻ: hook system AgentScope middleware software architecture Event Handling

Đăng vào ngày 28 tháng 6 lúc 03:23