Project overview — Reminder agent

9 — Workflows & AgentsTrung cấp15 phút

Agent goal: User says "Set a reminder for my doctor's appointment, it's a week from Thursday", system:

Bạn sẽ học được
  • Understand "set reminder" agent scope
  • Identify 3 gaps trong Claude's capability
  • Plan 3 tools để fill gaps
  • Set up project skeleton

Gap 1: Time awareness

Claude has training cutoff. "Current time" = ?

Solution: Tool get_current_datetime().

User: "What time is it now?"
Claude: "I cannot know current time precisely."

Gap 2: Date arithmetic

Claude can reason about dates but math errors with multi-day additions:

Solution: Tool add_duration_to_datetime(datetime, n, unit).

User: "What date is 103 days from today?"
Claude: Might make off-by-one errors, timezone confusion, etc.

Gap 3: No side-effect capability

Claude knows "set reminder" conceptually but can't actually schedule anything.

Solution: Tool set_reminder(text, when) — interacts with system.

Agent architecture

3 tool calls, natural language output. This is agent flow.

User: "Remind me 90 days from next Monday about renewal"
    │
    ▼
Claude (agent, has 3 tools):
    │
    ├─ Tool call 1: get_current_datetime() 
    │   → "2026-04-20" (Sunday)
    │
    ├─ Reason: next Monday = 2026-04-21
    │  No tool needed, Claude reasons natively
    │
    ├─ Tool call 2: add_duration_to_datetime(
    │     datetime="2026-04-21", duration=90, unit="days"
    │   )
    │   → "2026-07-20"
    │
    ├─ Tool call 3: set_reminder(
    │     text="renewal", remind_at_iso="2026-07-20T09:00:00"
    │   )
    │   → "Reminder created, ID: rem_abc"
    │
    └─ Response: "✓ Set reminder about renewal for July 20, 2026."

Tool schemas (recap from Module 5)

get_current_datetime

add_duration_to_datetime

@mcp.tool(
    name="get_current_datetime",
    description="Get current date/time. Use when user asks 'what time' or 'today' etc."
)
def get_current_datetime(date_format="%Y-%m-%d %H:%M:%S"):
    return datetime.now().strftime(date_format)

add_duration_to_datetime

set_reminder

@mcp.tool(
    name="add_duration_to_datetime",
    description="Add duration to datetime. Use for future/past date calculations."
)
def add_duration_to_datetime(datetime_str: str, duration: int, unit: str):
    dt = datetime.fromisoformat(datetime_str)
    delta = timedelta(**{unit: duration})
    return (dt + delta).isoformat()

set_reminder

@mcp.tool(
    name="set_reminder",
    description="Schedule a reminder. Use when user wants reminder/notification."
)
def set_reminder(reminder_text: str, remind_at_iso: str):
    if not reminder_text.strip():
        raise ValueError("Reminder text empty")
    dt = datetime.fromisoformat(remind_at_iso)
    if dt < datetime.now():
        raise ValueError(f"Reminder time in past: {dt}")
    # Actual save to DB/service
    reminder_id = save_to_db(reminder_text, dt)
    return f"Reminder created. ID: {reminder_id}. Will remind at {dt}"

Agent conversation loop

From Module 5 multi-turn:

Same loop pattern. Tools do heavy lifting.

async def run_reminder_agent(user_input: str):
    messages = []
    add_user_message(messages, user_input)
    
    for turn in range(10):
        response = chat(messages, tools=all_tools)
        add_assistant_message(messages, response)
        
        if response.stop_reason == "end_turn":
            return text_from_message(response)
        
        if response.stop_reason == "tool_use":
            results = run_tools_for_response(response)
            add_user_message(messages, results)
    
    raise RuntimeError("Max turns exceeded")

Test scenarios

Test each, observe agent behavior.

scenarios = [
    # Simple
    "What's the current time?",
    "Remind me to call mom in 2 hours",
    
    # Date arithmetic
    "What day is 100 days from today?",
    "Set reminder for my birthday (90 days after Oct 15, 2026)",
    
    # Complex
    "Remind me to renew license a week before March 15, 2027",
    "Set 3 reminders: 1 day, 1 week, 1 month after today about Xmas shopping",
    
    # Edge
    "Remind me yesterday" → should error (past)
    "Remind me in 0 days about nothing" → edge
]

Expected behavior

Simple case

"What's the current time?"

Complex case

"Set 3 reminders: 1 day, 1 week, 1 month about Xmas shopping"

Potentially 8 turns. OK — matches task complexity.

Or optimized: Claude may parallelize in 1 turn với multiple tool_use blocks.

  • Turn 1: get_current_datetime()
  • Turn 2: Response "The current time is ..."
  • Turn 1: get_current_datetime()
  • Turn 2: add_duration(+1 day)
  • Turn 3: add_duration(+1 week)
  • Turn 4: add_duration(+1 month)
  • Turn 5: set_reminder(text, +1 day)
  • Turn 6: set_reminder(text, +1 week)
  • Turn 7: set_reminder(text, +1 month)
  • Turn 8: Response confirming all

Project skeleton

reminder_agent/
├── .env
├── pyproject.toml
├── main.py          # conversation loop
├── tools.py         # 3 tools + schemas
└── test_cases.py    # eval scenarios

Success metrics

For each scenario:

Baseline → iterate.

  • ✅ Completed successfully?
  • ✅ Correct date computation?
  • ✅ Reasonable tool count (< 10 turns)?
  • ✅ Cost < $0.01 per request?

Real-world extensions

Beyond reminder:

But first — master 3 tool basic before expand.

  • Integrate với Calendar (Google, iCal)
  • Recurring reminders
  • Push notifications (real)
  • Timezone handling
  • Natural language with more complexity

Áp dụng ngay

Bài tập: Setup + baseline (30 phút)

  • Create project folder
  • Implement 3 tools
  • Build conversation loop
  • Test với 5 scenarios
  • Log tool call count per scenario

Tóm tắt

🎯 Agent project: reminder system.

🎯 3 tools fill 3 gaps in Claude's native capability.

🎯 Multi-turn loop: Claude chain tool calls.

🎯 Test diverse scenarios to verify agent robustness.

🎯 Extend later với Calendar integration, recurring, etc.

Nội dung này có hữu ích không?