中間件管道 (BETA)
BETA 功能
中間件管道目前處於測試階段。預設情況下已停用,需要明確配置才能啟用。
使用可插拔中間件擴展 GoZen,實現請求/回應轉換、日誌記錄、速率限制和自訂處理。
功能特性
- 可插拔架構 — 無需修改核心程式碼即可新增自訂處理邏輯
- 基於優先順序的執行 — 控制中間件執行順序
- 請求/回應鉤子 — 在傳送前處理請求,在接收後處理回應
- 內建中間件 — 上下文注入、日誌記錄、速率限制、壓縮
- 插件載入器 — 從本地檔案或遠端 URL 載入中間件
- 錯誤處理 — 優雅的錯誤處理和回退行為
架構
客戶端請求
↓
[中間件 1: 優先順序 100]
↓
[中間件 2: 優先順序 200]
↓
[中間件 3: 優先順序 300]
↓
提供商 API
↓
[中間件 3: 回應]
↓
[中間件 2: 回應]
↓
[中間件 1: 回應]
↓
客戶端回應
配置
啟用中間件管道
{
"middleware": {
"enabled": true,
"pipeline": [
{
"name": "context-injection",
"enabled": true,
"priority": 100,
"config": {}
},
{
"name": "request-logger",
"enabled": true,
"priority": 200,
"config": {
"log_level": "info"
}
}
]
}
}
選項:
| 選項 | 描述 |
|---|---|
enabled | 啟用中間件管道 |
pipeline | 中間件配置陣列 |
name | 中間件識別符 |
priority | 執行順序(越小越早) |
config | 中間件特定配置 |
內建中間件
1. 上下文注入
向請求中注入自訂上下文。
{
"name": "context-injection",
"enabled": true,
"priority": 100,
"config": {
"system_prompt": "你是一個有用的編碼助手。",
"metadata": {
"session_id": "sess_123",
"user_id": "user_456"
}
}
}
使用場景:
- 新增系統提示
- 注入會話中繼資料
- 新增使用者上下文
2. 請求日誌記錄器
記錄所有請求和回應。
{
"name": "request-logger",
"enabled": true,
"priority": 200,
"config": {
"log_level": "info",
"log_body": false,
"log_headers": true
}
}
使用場景:
- 除錯
- 稽核追蹤
- 效能監控
3. 速率限制器
限制每個提供商或全域的請求速率。
{
"name": "rate-limiter",
"enabled": true,
"priority": 300,
"config": {
"requests_per_minute": 60,
"burst": 10,
"per_provider": true
}
}
使用場景:
- 防止速率限制錯誤
- 控制 API 使用
- 防止濫用
4. 壓縮 (BETA)
當 token 數量超過閾值時壓縮上下文。
{
"name": "compression",
"enabled": true,
"priority": 400,
"config": {
"threshold_tokens": 50000,
"target_tokens": 20000
}
}
詳見上下文壓縮。
5. 會話記憶 (BETA)
跨會話維護對話記憶。
{
"name": "session-memory",
"enabled": true,
"priority": 150,
"config": {
"max_memories": 100,
"ttl_hours": 24,
"storage": "sqlite"
}
}
使用場景:
- 記住使用者偏好
- 追蹤對話歷史
- 跨會話維護上下文
6. 編排 (BETA)
將請求路由到多個提供商並聚合回應。
{
"name": "orchestration",
"enabled": true,
"priority": 500,
"config": {
"strategy": "parallel",
"providers": ["anthropic", "openai"],
"consensus": "longest"
}
}
使用場景:
- 比較模型輸出
- 關鍵請求的冗餘
- 透過共識提高品質
自訂中間件
中間件介面
type Middleware interface {
Name() string
Priority() int
ProcessRequest(ctx *RequestContext) error
ProcessResponse(ctx *ResponseContext) error
}
type RequestContext struct {
Provider string
Model string
Messages []Message
Metadata map[string]interface{}
}
type ResponseContext struct {
Provider string
Model string
Response *APIResponse
Latency time.Duration
Metadata map[string]interface{}
}
範例:自訂標頭注入
package main
import (
"github.com/dopejs/gozen/internal/middleware"
)
type CustomHeaderMiddleware struct {
headers map[string]string
}
func (m *CustomHeaderMiddleware) Name() string {
return "custom-headers"
}
func (m *CustomHeaderMiddleware) Priority() int {
return 250
}
func (m *CustomHeaderMiddleware) ProcessRequest(ctx *middleware.RequestContext) error {
for k, v := range m.headers {
ctx.Metadata[k] = v
}
return nil
}
func (m *CustomHeaderMiddleware) ProcessResponse(ctx *middleware.ResponseContext) error {
// 不需要回應處理
return nil
}
func init() {
middleware.Register("custom-headers", func(config map[string]interface{}) middleware.Middleware {
return &CustomHeaderMiddleware{
headers: config["headers"].(map[string]string),
}
})
}
載入自訂中間件
本地插件
{
"middleware": {
"enabled": true,
"plugins": [
{
"type": "local",
"path": "/path/to/custom-middleware.so",
"config": {
"headers": {
"X-Custom-Header": "value"
}
}
}
]
}
}
遠端插件
{
"middleware": {
"enabled": true,
"plugins": [
{
"type": "remote",
"url": "https://example.com/middleware/custom-headers.so",
"checksum": "sha256:abc123...",
"config": {}
}
]
}
}
Web UI
在 http://localhost:19840/settings 存取中間件設定:
- 導覽到 "Middleware" 標籤(標有 BETA 徽章)
- 切換 "Enable Middleware Pipeline"
- 從管道中新增/刪除中間件
- 調整優先順序和配置
- 啟用/停用單個中間件
- 點選 "Save"
API 端點
列出中間件
GET /api/v1/middleware
回應:
{
"enabled": true,
"pipeline": [
{
"name": "context-injection",
"enabled": true,
"priority": 100,
"type": "builtin"
},
{
"name": "request-logger",
"enabled": true,
"priority": 200,
"type": "builtin"
}
]
}
新增中間件
POST /api/v1/middleware
Content-Type: application/json
{
"name": "rate-limiter",
"enabled": true,
"priority": 300,
"config": {
"requests_per_minute": 60
}
}
更新中間件
PUT /api/v1/middleware/{name}
Content-Type: application/json
{
"enabled": false
}
刪除中間件
DELETE /api/v1/middleware/{name}
重新載入管道
POST /api/v1/middleware/reload
使用場景
開發環境
新增除錯日誌和請求檢查:
{
"middleware": {
"enabled": true,
"pipeline": [
{
"name": "request-logger",
"enabled": true,
"priority": 100,
"config": {
"log_level": "debug",
"log_body": true
}
}
]
}
}
生產環境
新增速率限制和監控:
{
"middleware": {
"enabled": true,
"pipeline": [
{
"name": "rate-limiter",
"enabled": true,
"priority": 100,
"config": {
"requests_per_minute": 100,
"burst": 20
}
},
{
"name": "request-logger",
"enabled": true,
"priority": 200,
"config": {
"log_level": "info",
"log_body": false
}
}
]
}
}
多提供商比較
使用編排來比較輸出:
{
"middleware": {
"enabled": true,
"pipeline": [
{
"name": "orchestration",
"enabled": true,
"priority": 500,
"config": {
"strategy": "parallel",
"providers": ["anthropic", "openai", "google"],
"consensus": "longest"
}
}
]
}
}
最佳實務
- 使用適當的優先順序 — 較小的數字先執行
- 保持中間件專注 — 每個中間件應該做好一件事
- 優雅地處理錯誤 — 不要因錯誤而破壞管道
- 徹底測試 — 在生產前驗證中間件行為
- 監控效能 — 追蹤中間件開銷
- 記錄配置 — 清楚地記錄配置選項
限制
- 效能開銷 — 每個中間件都會增加延遲
- 複雜性 — 太多中間件會使除錯變得困難
- 插件安全 — 遠端插件需要信任和驗證
- 錯誤傳播 — 中間件錯誤會影響所有請求
- 配置複雜性 — 複雜的管道更難維護
疑難排解
中間件未執行
- 驗證
middleware.enabled為true - 檢查中間件在管道中已啟用
- 驗證優先順序設定正確
- 查看守護程式日誌中的中間件錯誤
意外行為
- 檢查中間件執行順序(優先順序)
- 驗證配置是否正確
- 單獨測試中間件
- 查看中間件日誌
效能問題
- 識別慢速中間件(檢查日誌)
- 減少中間件數量
- 最佳化中間件實作
- 考慮停用非必要的中間件
插件載入失敗
- 驗證插件路徑是否正確
- 檢查插件是否為正確的架構編譯
- 驗證校驗和匹配(對於遠端插件)
- 查看插件日誌中的錯誤
安全考量
- 驗證插件 — 僅載入受信任的插件
- 驗證校驗和 — 始終驗證遠端插件校驗和
- 沙箱插件 — 考慮在隔離環境中執行插件
- 稽核中間件 — 在部署前審查中間件程式碼
- 監控行為 — 注意意外的中間件行為
未來增強
- WebAssembly 插件支援以實現跨平台相容性
- 用於共享社群插件的中間件市場
- Web UI 中的視覺化管道編輯器
- 中間件效能分析
- 插件更新的熱重載
- 中間件測試框架