Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 4 — Xây bộ tool quản lý lịch & task đầy đủ (đọc–ghi–xóa an toàn)

Đã đọc 0/7 mục · còn khoảng 3 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Bài 4 — Xây bộ tool quản lý lịch & task đầy đủ

Bài 3 agent mới đọc và thêm. Bài này ta hoàn thiện bộ CRUD: tạo, dời, xóa event và task — kèm cổng xác nhận cho mọi thao tác ghi, đúng nguyên tắc "Đọc tự do — Ghi có kiểm soát" từ bài 1.

Danh mục tool tối thiểu

ToolLoạiCần xác nhận?
list_events(range)đọcKhông
list_tasks()đọcKhông
create_event(title, start, end)ghiCó
move_event(id, new_start)ghiCó
delete_event(id)xóaCó
add_task(content, due)ghiCó
complete_task(id)ghiCó (nhẹ)

Cơ chế cổng xác nhận (2 bước)

Mẹo thực chiến: tách mọi hành động ghi thành hai giai đoạn — preview (chuẩn bị, không đụng dữ liệu) và confirm (thực thi). Agent trả preview cho người dùng, chỉ khi có "OK" mới chạy confirm.

PENDING = {}

def create_event_preview(title, start, end):
    token = str(hash((title, start)))
    PENDING[token] = {"title": title, "start": start, "end": end}
    return {"preview": f"Tạo '{title}' lúc {start}", "confirm_token": token}

def confirm_action(confirm_token):
    data = PENDING.pop(confirm_token, None)
    if not data:
        return {"error": "Token hết hạn, hãy thử lại."}
    ev = cal.events().insert(calendarId="primary", body={
        "summary": data["title"],
        "start": {"dateTime": data["start"]},
        "end": {"dateTime": data["end"]}}).execute()
    return {"status": "created", "id": ev["id"]}

Agent gọi create_event_preview, nói với người dùng "Mình sẽ tạo... xác nhận nhé?", rồi gọi confirm_action khi được đồng ý.

Các bước phát hiện xung đột lịch

Một agent lịch tử tế phải cảnh báo trùng giờ:

  • Trước khi tạo/dời, gọi list_events trong khung giờ đích.
  • Kiểm tra chồng lấn: new_start < ev_end AND new_end > ev_start.
  • Nếu trùng, đưa cảnh báo vào preview: "Giờ này đã có 'Họp team'."
  • Gợi ý 1-2 khung trống gần nhất.
  • Để người dùng quyết định, không tự ý ghi đè.
def overlaps(a_start, a_end, b_start, b_end):
    return a_start < b_end and a_end > b_start

Ví dụ cụ thể

Người dùng: "Đặt họp review 3h chiều mai 1 tiếng." Agent: gọi list_events mai 15:00-16:00 → phát hiện đã có "1:1 với sếp" → trả preview kèm cảnh báo và đề xuất 16:00. Người dùng: "Ừ để 4h." → agent preview lại → xác nhận → tạo.

Khung tư duy: mọi thao tác ghi = 3 câu hỏi

  • Idempotent không? Gọi hai lần có tạo trùng không? Nếu có, cần token/khóa chống lặp.
  • Đảo ngược được không? Xóa event có undo được không? Nếu không, cảnh báo mạnh hơn.
  • Đã xác nhận chưa? Không confirm thì không ghi.

Sai lầm thường gặp

  • Cho agent xóa không hỏi. "Dọn lịch tuần này" mà agent tự xóa hết là thảm họa. Xóa luôn cần xác nhận rõ từng mục.
  • Bỏ qua kiểm tra trùng lịch. Agent đặt chồng cuộc họp làm người dùng mất niềm tin ngay lần đầu.
  • Token xác nhận không hết hạn. Người dùng "OK" một hành động cũ từ 2 tiếng trước có thể kích hoạt nhầm; đặt TTL cho PENDING.
  • Không phân biệt id nội bộ và tiêu đề. Agent "dời cuộc họp" nhưng có 2 cuộc trùng tên → phải hỏi rõ cuộc nào, dùng event id chứ không dùng tên.
  • Ghi thẳng vào lịch chính khi test. Vẫn dùng calendar phụ cho tới khi luồng confirm ổn định.
Chốt bài: Agent đã CRUD được lịch/task an toàn, biết cảnh báo trùng giờ. Bài 5 ta dạy nó phần khó nhất: tự ưu tiên công việc.

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