# LLM Smart Route 🚀

> **A lightweight, non-intrusive self-healing model router for LLM applications.**

[![PyPI version](https://img.shields.io/pypi/v/llm-smart-route.svg)](https://pypi.org/project/llm-smart-route/)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI Status](https://github.com/YuChieh-Chiu/LLM-Smart-Route/actions/workflows/ci.yml/badge.svg)](https://github.com/YuChieh-Chiu/LLM-Smart-Route/actions/workflows/ci.yml)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

`llm-smart-route` 是一個輕量的 Python Decorator 套件，專為解決 LLM 模型生命週期管理而生。當您指定的模型因供應商更新或棄用而失效時，此工具會自動偵測並切換至同家族的最佳候選版本，確保您的生產環境服務不中斷。

---

## 📌 目錄

- [✨ 核心特點](#-核心特點)
- [🚀 快速開始](#-快速開始)
    - [安裝](#安裝)
    - [基礎用法](#基礎用法)
- [🤖 供應商支援矩陣](#-供應商支援矩陣)
- [⚙️ 進階配置](#-進階配置)
    - [通知功能](#通知功能)
    - [持久化快取](#持久化快取)
    - [自訂參數](#自訂參數)
- [🛠️ 工作原理](#-工作原理)
- [📖 文檔與範例](#-文檔與範例)
- [🧪 開發與測試](#-開發與測試)
- [📜 授權](#-授權)

---

## ✨ 核心特點

- 🧠 **智慧路由 (Self-healing)**: 自動捕獲模型失效異常，動態查詢並切換至同家族最佳候選版本。
- 🔌 **非侵入性設計**: 無須改動現有 SDK 呼叫邏輯，僅需掛載一個 `@smart_model` 裝飾器。
- 💾 **持久化快取 (Persistence)**: 記憶成功的模型替換映射，顯著降低 API 偵測開銷。
- 🔔 **主動警報**: 支援 Slack、Line 與自訂通知器，讓開發者即時掌握模型更新。
- 🚀 **極致輕量**: 核心僅依賴標準庫與必要的供應商 SDK (可選安裝)。
- 🌍 **多供應商支援**: 深度整合 Anthropic, Google, OpenAI, Alibaba, Mistral 等主流 AI 模型。

---

## 🚀 快速開始

### 安裝

您可以根據需求選擇安裝核心功能或特定供應商支援：

```bash
# 基礎安裝
pip install llm-smart-route

# 針對特定供應商與通知功能安裝 (推薦)
pip install "llm-smart-route[gemini,slack]"
pip install "llm-smart-route[all]"
```

### 基礎用法

只需在您的模型呼叫函數上掛載裝飾器：

```python
from llm_smart_route import smart_model
import anthropic

@smart_model(provider="claude", model="claude-3-5-sonnet-20241022")
def ask_ai(model: str, prompt: str):
    # 如果 claude-3-5-sonnet 過期, Decorator 會自動將 model 替換為最新版 (例如 claude-4-5-sonnet)
    client = anthropic.Anthropic()
    return client.messages.create(
        model=model,
        messages=[{"role": "user", "content": prompt}]
    )

# 像往常一樣正常呼叫
response = ask_ai(prompt="Hello, who are you?")
```

---

## 🤖 供應商支援矩陣

| 供應商 (Provider) | 別名 (Aliases) | 建議標籤 | 支援 SDK |
| :--- | :--- | :--- | :--- |
| **Anthropic** | `claude`, `anthropic` | `haiku`, `sonnet`, `opus` | `anthropic` |
| **Google** | `gemini`, `google` | `flash`, `pro` | `google-genai` |
| **OpenAI** | `openai`, `gpt` | `mini`, `o1`, `gpt-4o` | `openai` |
| **Alibaba** | `qwen`, `alibaba` | `turbo`, `plus`, `max` | `dashscope` |
| **Mistral** | `mistral` | `small`, `medium`, `large` | `mistralai` |

---

## ⚙️ 進階配置

### 通知功能

當發生模型自動替換時，您可以設定主動通知：

```python
from llm_smart_route import smart_model, create_slack_notifier

slack_notify = create_slack_notifier() # 預設讀取環境變數 SLACK_BOT_TOKEN

@smart_model(provider="openai", model="gpt-4o-mini", on_replace=slack_notify)
def call_gpt(model, prompt):
    ...
```

### 持久化快取

您可以自訂快取檔案路徑，以便在不同的執行環境中共享模型映射：

```python
from llm_smart_route import configure_cache

configure_cache(cache_path="./data/router_cache.json")
```

---

## 🛠️ 工作原理

`llm-smart-route` 採用「攔截-偵測-修復」的工作流：

1. **攔截**: Decorator 接入並讀取配置。
2. **偵測**: 執行函數，若觸發 `ModelNotFoundError` 類型的異常，則進入自動修復。
3. **修復**:
    - 查詢 Provider API 獲取 Active 模型清單。
    - 基於語意與關鍵字匹配同系列模型。
    - 依據版本號進行排序與選擇。
4. **驗證與快取**: 使用新模型重試，成功後將映射存入快取文件，效期內不再重複查詢。

---

## 📖 文檔與範例

- 📐 [架構設計文件](docs/DESIGN.md) - 詳細設計理念與系統架構
- 📂 [範例代碼](docs/examples/) - 涵蓋非同步、Dry Run 等多種場景
- 🛡️ [安全策略](SECURITY.md) - 漏洞回報流程與支援版本

---

## 🧪 開發與測試

本專案使用 `Poetry` 進行依賴管理與 `pytest` 測試。

```bash
# 安裝開發依賴
poetry install

# 執行單元測試
poetry run pytest tests/unit/
```

---

## 📄 授權

基於 **MIT License** 開源。詳見 [LICENSE](LICENSE) 文件。
