跳轉到

Time Compass 系統架構快速導覽

用途: 30 秒了解系統構成
對象: 新開發者、架構師、決策者
深入指南: → 各主題參考


C1: System Context(系統邊界)

Time Compass 是一個時程調度規劃助手,與三個外部系統通信:

graph TB
    User["👤 使用者<br/>(網頁/AI助理)"]
    TC["📱 Time Compass<br/>(調度規劃系統)"]
    GC["Google Calendar"]
    GT["Google Tasks"]
    Moodle["Moodle 課程管理系統<br/>(爬蟲)"]

    User -->|提問、拖放事件| TC
    TC -->|查詢/創建| GC
    TC -->|查詢/創建| GT
    TC -->|爬蟲取資料| Moodle

    GC -->|日程事件| TC
    GT -->|工作清單| TC
    Moodle -->|課程、截止日期| TC

C2: Containers(主要服務)

系統採用 MCP-First 並行雙入口架構,同時維持舊 Gradio 容器支援:

graph TB
    subgraph "接入層"
        MCP["🔌 MCP Server<br/>(新推薦)"]
        Gradio["🎨 Gradio Web UI<br/>(遺留)"]
        Planner["🎨 Planner Studio<br/>(微前端)"]
    end

    subgraph "業務邏輯層"
        Core["⚙️ async_core<br/>"]
        Integration["🔌 Integration Layer<br/>(Google, Moodle)"]
    end

    subgraph "資料層"
        DB["💾 Cache"]
    end

    external["🌍 外部 API"]

    Planner -->|MCP 工具呼叫| MCP
    Gradio -->|HTTP Tab 互動| Core
    MCP -->|編排工具、觸發任務| Core
    Core -->|轉換、一致性檢查| Integration
    Integration -->|API 呼叫| external
    external -->|回應| Integration
    Integration -->|更新| DB
    Core -->|查詢| DB

各容器責任

容器 架構地位 職責 關鍵組件 啟動方式
MCP Server 🟢 推薦 暴露 15 個工具給 Claude/Cursor IDE src/time_compass/mcp/server.py、15 個工具 uv run time-compass-mcp
Gradio Web UI 🟡 並行支援 獨立網頁 Tab 式介面(port 8000) src/time_compass/interface/server.py、5 個 Tab uv run time-compass-gradio
Planner Studio 🟢 推薦 零框架縮放排程工具 FullCalendar 6.1 + 自製縮放、衝突 detection MCP 內 launch_planner_studio() 工具觸發
async_core 核心 編排 DDD、驅動 Prompts、統一錯誤處理 integrations/async_core.py、Result Monad -
Integration Layer 核心 統一 Google/Moodle API 呼叫、資料轉換管道 integrations/{google_calendar, google_tasks, moodle}/async_core.py -
Data/Cache 底層 事件、任務、課程資料快取 本地或 Google Cloud 存儲 -

架構地位說明: - 🟢 推薦:符合現代設計,計劃持續投資 - 🟡 並行支援:仍可用,與推薦並行,但不再主要特性開發 - 🔴 遺留:已停止維護(此系統無此類)

容器選擇指南

我是 AI 助理開發者 → 使用 MCP Server
我要手動管理排程 → 使用 Gradio Web UIPlanner Studio
我要整合新的資料來源 → 修改 Integration Layer


Gradio Web UI 工作流程(並行容器)

Gradio 是同步 Web 介面,提供 5 個互動 Tab,但重點在於與 Orchestrator 的協作。用戶輸入驅動完整的 AI 決策流水線:

graph TB
    User["👤 使用者<br/>(瀏覽器輸入)"]

    subgraph Gradio["🎨 Gradio Web UI (port 8000)"]
        OAuth["🔐 OAuth<br/>Tab 1"]
        Debug["🐛 Debug/Test<br/>Tab 2"]
        GoogleTasks["✅ Google Tasks<br/>Tab 3"]
        Scheduling["📅 Scheduling<br/>Tab 4"]
        Moodle["📚 Moodle<br/>Tab 5"]
    end

    subgraph AI["🧠 AI 決策層 (Orchestrator)"]
        Router["Router<br/>(決定流程)"]
        Pipeline["Pipeline<br/>(多模組序列)"]
    end

    subgraph Backend["⚙️ Integration Layer<br/>(並行抓取)"]
        Cal["Google Calendar"]
        Task["Google Tasks"]
        Mood["Moodle"]
    end

    User -->|提問或請求| Scheduling
    Scheduling -->|user_input| Router
    Router -->|pipeline決定| Pipeline

    Backend -.->|並行抓取<br/>(Summary/Scheduling<br/>讀取)| Pipeline
    Pipeline -->|EmotionSupport<br/>Summary<br/>Scheduling| StreamOutput["串流輸出"]

    Scheduling -->|寫入<br/>(直接)| Task

    StreamOutput -->|更新UI| Scheduling
    Scheduling -.->|展示結果| User

    OAuth -.->|管理 Token| OAuth
    Debug -.->|測試 API| Debug
    GoogleTasks -.->|列表檢視| GoogleTasks
    Moodle -.->|爬蟲課程| Moodle

Gradio 中的 AI 互動流程

步驟 元件 職責
1. 用戶輸入 Scheduling Tab 接收自由文字提問
2. 路由決策 Router Module 分析意圖,決定要執行的 Pipeline(情緒支持 → 摘要 → 排程等)
3. 並行抓取 Integration Layer 同時取 Google Calendar/Tasks/Moodle 資料(背景進行)
4. 資料注入 Summary/Scheduling 模組 將抓取的資料注入 InteractionContext
5. 流程編排 Pipeline Executor 依序執行各模組,每個模組讀取 Context 中的資料
6. 串流回應 streaming.py 逐 chunk 推送結果回前端(格式:[Module:field] text
7. 寫入操作 Scheduling Tab 若用戶確認排程,直接寫入 Google Tasks
8. UI 更新 Gradio ChatInterface 即時顯示 AI 回應與建議

Gradio 的 5 個 Tab

Tab 功能 資料流 核心操作
🔐 OAuth Login Google OAuth 授權、token 管理 同步 初始授權 → Token 刷新 → 帳號切換
🐛 Debug/Test Request 直接呼叫 API 測試、查看回應 同步 構造要求 → 執行 → 檢視原始回應
✅ Google Tasks 管理 Google Tasks 工作列表 同步 列表查看 → 建立任務 → 更新狀態 → 刪除任務
📅 Scheduling & Planning AI 輔助排程(核心) 異步 + Pipeline 輸入 → Router → Pipeline(讀 Integration 資料) → 寫 Google Tasks
📚 Moodle Integration 爬蟲取課程資訊、截止日期 同步爬蟲 帳號登入 → 爬蟲課程 → 檢視課程事件

Scheduling Tab 內的 AI 互動細節: - 使用者提問 → Orchestrator.forward(user_input) 呼叫 - 並行背景:Integration Layer 同時抓取 Google Calendar、Google Tasks、Moodle 資料 - Router 模組決定 Pipeline:[EmotionSupport → Summary → Scheduling] 等序列 - 各模組接收 InteractionContext(含歷史、上下文、已抓取的時程資料) - Summary 和 Scheduling 模組從 Context 讀取 Calendar/Tasks/Moodle 資料,無需再次 API 呼叫 - 串流回應逐 chunk yield,格式為 [ModuleName:FieldName] content - 寫入時:用戶確認建議 → 直接呼叫 Google Tasks write API - 前端即時更新 ChatInterface 顯示結果與建議

詳見:docs/time_compass/domain/orchestrator.md

Gradio 與 Integration Layer 的互動

Gradio 與 MCP 都是通過 Integration Layer 的統一 API 呼叫資料來源:

讀取操作:
├─ Gradio: async_get_all_tasks() / async_get_all_events() / scrape_moodle_events()
└─ MCP: 相同的 API(無框架耦合)

寫入操作:
├─ Gradio: async_task_insert()(Google Tasks 寫入) 
└─ MCP: 相同的 API(透過工具呼叫)

核心相同性:Gradio 與 MCP 都使用 Integration Layer 中的統一 async 函數,無需關心底層 Batch API 細節。


Orchestrator 與 AI 決策層(C3 邏輯編排)

Gradio 和 MCP 都透過 Orchestrator 驅動 AI 決策。Orchestrator 的核心職責是協調多個 LLM 模組形成完整的推理流水線:

graph TB
    UserInput["使用者輸入<br/>(自由文字)"]
    Orch["Orchestrator<br/>(編排器)"]
    Router["🧭 Router Module<br/>(意圖分析)"]

    Pipeline["📊 Pipeline<br/>(決策序列)"]
    Emotion["EmotionSupport<br/>(情緒陪伴)"]
    Summary["Summary<br/>(活動回顧)"]
    Sched["Scheduling<br>(排程建議)"]

    Context["InteractionContext<br>(對話上下文 + 時程資料)"]
    Integration["Integration Layer<br>(Google + Moodle 資料)"]

    Output["final_reply<br>(整合回應)"]

    UserInput -->|user_input| Orch
    Orch -->|dialog_history| Router
    Router -->|pipeline決定<br>(順序 & 模組)| Pipeline

    Pipeline -->|分派| Emotion
    Pipeline -->|分派| Summary
    Pipeline -->|分派| Sched

    Orch -->|構建| Context
    Context -->|包含| Integration

    Emotion -->|InteractionContext| Pipeline
    Summary -->|InteractionContext| Pipeline
    Sched -->|InteractionContext| Pipeline

    Pipeline -->|聚合輸出| Output

Orchestrator 工作流程

  1. Router 分析意圖:根據 user_input 決定 Pipeline 序列
  2. 例:用戶「這週很累」→ Pipeline = [EmotionSupport → Summary → ask_question]

  3. 構建 InteractionContext:收集對話歷史、時程資料、之前模組的輸出

  4. 依序執行 Pipeline:每個模組接收完整的 Context,回傳結構化輸出

  5. 優先級邏輯(由 Router 決策,不同情境不同):

  6. 純規劃場景 → [Scheduling]
  7. 迷茫/疲勞場景 → [EmotionSupport → ask_question → draft_plan]
  8. 總結場景 → [Summary → draft_plan → draft_action]

  9. Streaming 輸出(Gradio 特性):邊執行邊 yield chunk,每個 chunk 標記模組與欄位:

    [Router:pipeline_description] 我會幫你規劃...
    [EmotionSupport:output] 聽起來你這週...
    [Summary:summary_text] 過去三天的活動...
    [Scheduling:draft_schedule] 建議時段:...
    

Pipeline 的標準模組

模組 用途 輸入 輸出
Router 意圖分析與流程決策 user_input, dialog_history pipeline, pipeline_description
EmotionSupport 心理陪伴(若需要) InteractionContext support_text, action_suggestion
Summary 區間活動回顧 InteractionContext + calendar/tasks 資料 summary_text, insights
Scheduling 排程建議與衝突檢測 InteractionContext + 完整時程資料 draft_schedule, risks, next_steps
ask_question 澄清缺失資訊 InteractionContext questions, constraints, follow_up_suggestion

詳細說明與流程圖:docs/time_compass/domain/orchestrator.md


Gradio 與 MCP 共享的 Orchestrator

兩個容器都使用相同的 Orchestrator,區別在: - Gradio:同步 HTTP 請求 → orch.forward(input) → 串流回應 - MCP:工具調用 → get_time_context() + draft_plan_prompt() → 提示回傳

這是「多入口同邏輯」的典型設計。

Integration Layer(C3 實現細節)

三個整合模組

integrations/
├── common/                      ← 共通層
│   ├── exceptions.py           (8 種 GoogleError 定義)
│   ├── google_api_dispatcher.py (Batch API 分派器、HTTP Multipart 編碼)
│   └── ...
│
├── google_calendar/             ← Google Calendar 模組
│   ├── async_core.py            (取日程、建事件、查詢時段)
│   └── models/
│       ├── models_raw.py        (47+欄位,camelCase)
│       ├── models_read.py       (datetime 保留,應用層最佳化)
│       └── models_toon.py       (索引地點、重複規則、TOON 編碼)
│
├── google_tasks/                ← Google Tasks 模組
│   ├── async_core.py            (取清單、建工作、狀態管理)
│   └── models/
│       ├── models_raw.py        (18 欄位)
│       ├── models_read.py       (Eager-cast 為字串)
│       └── models_toon.py       (按狀態分組、TOON 編碼)
│
└── moodle/                      ← Moodle 爬蟲模組
    ├── async_core.py            (Web Scraper + OIDC + Selenium)
    └── models/
        ├── models_raw.py        (55+ 欄位)
        ├── models_internal.py   (HTML 清洗、時區轉 UTC+8)
        ├── models_read.py       (語意化狀態、8 欄位精簡)
        └── ...

四層資料模型

每個模組都遵循 Raw → Internal → Read → TOON 轉換:

用途 例:Calendar
Raw 100% API 映射,無修改 GoogleEventRaw(47 欄位,camelCase)
Internal/Domain 反腐層,清洗格式 GoogleEventRead(datetime 物件保留)
Read 應用層最佳化 ToonCalendar(索引化地點、日期元件化)
TOON 極致壓縮 TOON 字串格式(Token 節省 83.7%)

錯誤處理(Railway-Oriented)

所有操作返回 Result[T],不拋異常:

Result[ListEventsResponse] = Ok(events) | Err(GoogleAuthError(...))

8 種錯誤分類: - GoogleAuthError (401/403) → 需用戶重新授權 - GoogleNetworkError (timeout) → 指數退避重試 - GoogleParseError (JSON) → 記錄,上報bug - GoogleRateLimitError (429) → 可重試 - GoogleNotFoundError (404) → 忽略或提示用戶 - ...等

詳細說明: → ERROR-HANDLING


資料轉換流水線

graph LR
    Raw["外部 API JSON<br/>(Raw Layer)"]
    Internal["內部轉換<br/>(HTML 清洗、時區轉)<br/>(Internal Layer)"]
    Read["讀取模型<br/>(應用層最佳化)<br/>(Read Layer)"]
    TOON["TOON 格式<br/>(極致壓縮)<br/>83.7% token 節省"]

    Raw -->|from_dict| Internal
    Internal -->|to_read| Read
    Read -->|safe_encode| TOON

詳細解釋: → DDD-ARCHITECTURE


C3: Integration 層(資料來源通訊)

時程規劃系統的關鍵:與三個外部資料源並行通信。

graph TB
    subgraph Integration["🔌 Integration Layer"]
        Common["共通層<br/>exceptions.py<br/>google_api_dispatcher.py<br/>http_batch_tool.py"]

        subgraph Google["Google API (Batch 模式)"]
            Cal["Google Calendar<br/>async_get_all_events()"]
            Task["Google Tasks<br/>async_get_all_tasks()"]
        end

        Moodle["Moodle (Web 爬蟲)<br/>scrape_moodle_events()"]

        Coord["🔥 頂級協調<br/>async_get_all_information_from_api()"]
    end

    Common -.->|支援| Google
    Common -.->|支援| Moodle

    Cal -->|結果| Coord
    Task -->|結果| Coord
    Moodle -->|結果| Coord

    Coord -->|返回| ResourceContext["ResourceContext<br/>(三合一結果)"]

    style Common fill:#fff3e0
    style Google fill:#f3e5f5
    style Moodle fill:#fce4ec
    style Coord fill:#e1f5fe

Integration 層三大支柱

支柱 技術 特點
Google APIs Batch API + 非同步 Generator 多個日曆/工作列表並行,自動分頁,速度快
Moodle 爬蟲 OIDC 登入 + Selenium Fallback 課程資訊抓取,60s 超時保障
共通層 Dispatcher + Multipart Builder 統一例外體系、Type-Safe 回傳、結構化 Batch 請求

深入指南: - � 完整 C4 Model 文檔: ../reference/INTEGRATION/C4_MODEL.md(涵蓋 L1-L4 四層)


核心設計原則

Railway-Oriented Programming

所有操作使用 Result[T] 型別,明確表達成功/失敗,避免例外被吞掉。
深入了解: → ERROR-HANDLING

多源並行抓取

Google Calendar、Google Tasks、Moodle 並行執行,每個獨立失敗且有重試機制。
工具手冊: → MCP-TOOLS

零框架前端

Vanilla JavaScript,無打包步驟,<500ms 啟動。
實作指南: → FRONTEND


Prompts 系統設計(雙源非 SOT)

系統的 Prompt 定義採用非 SOT(Single Source of Truth)設計 - 由 Gradio 時代(domain/)和 MCP 時代(mcp/prompts/)各自維護一份:

domain/ (舊 DSPy/Gradio 時代)
├── summary/prompt/
│   ├── summary_tool.md      ( LLM 工具簽名 )
│   └── summary_writer.md    ( 活動回顧工具 )
├── schedule/prompt/
│   ├── router.md            ( 路由邏輯 )
│   ├── draft_plan.md        ( 初步規劃 )
│   ├── draft_action.md      ( 可執行排程 )
│   └── ask_question.md      ( 澄清問題 )
└── router/prompt/
    └── ...

mcp/prompts/ (新 MCP 時代)
├── domain_prompts.py        ( 函數定義 + 載入器 )
└── content/
    ├── summary_writer.md    (↑ 對應 domain/ 版本)
    ├── emotion_support.md   (新增,Gradio 無)
    ├── draft_plan_prompt.md
    ├── draft_action_prompt.md
    ├── scheduling_router_prompt.md
    └── ...

為什麼非 SOT? - ✅ 獨立演進:Gradio 和 MCP 可各自迭代 Prompt,無需同步 - ✅ 已知差異:系統隨時意識到雙版本可能不同步,監控標記已設置 - ✅ 漸進遷移:無需一次性遷移所有 Prompt,可按需逐步更新

如何同步? 詳見 ADR-0010: 文檔類資源統一架構


想深入某個主題?

選擇妳的探索路徑:

我想... 去這裡
理解四層資料轉換(Raw → Internal → Read → TOON) DDD-ARCHITECTURE
詳細了解 Integration 層(Google + Moodle 通信) Integration C4 Model
了解 Orchestrator 與 Router 如何運作 docs/time_compass/domain/orchestrator.mdrouter.md
學習各 Pipeline 模組的設計 emotion.mdsummary.mdscheduling/
了解串流如何工作(Gradio 特性) docs/time_compass/domain/orchestrator.md
了解錯誤處理怎麼做(為什麼用 Railway?) ERROR-HANDLING
學習 15 個 MCP 工具的設計與用法 MCP-TOOLS
看前端零框架怎麼運作(FullCalendar + 縮放) FRONTEND
查看整個系統的資料流圖 data-flow.md
了解開發模式設計決策 DEV_MODE_GUIDE.md
理解 Prompts 為什麼非 SOT 設計 ADR-0010

推薦的新手閱讀順序

  1. 第一遍(15 分鐘):讀本頁,了解 C1-C2 邊界與容器
  2. 第二遍(30 分鐘):進 reference/README.md 選一個主題深入
  3. 第三遍(1 小時+):依據工作需要在各主題中深潜

往更上層看

想了解為什麼做了這些架構選擇?
Architecture Decision Records (ADR) - 從 ADR-0001 開始

想知道團隊的願景?
願景與故事