Files
AI-Proxy-Worker/docs/Examples.md
2025-08-17 19:59:10 +08:00

24 KiB

使用示例

🌍 Language / 语言

🇺🇸 English | 🇨🇳 中文

各种编程语言和框架集成 AI Proxy Worker 的实用示例。复制并调整这些示例以适应你的具体使用场景。

🌐 Web 应用

JavaScript (原生)

基本网页实现:

<!DOCTYPE html>
<html>
<head>
    <title>AI 聊天演示</title>
    <meta charset="UTF-8">
</head>
<body>
    <div id="chat-container">
        <div id="messages"></div>
        <input type="text" id="user-input" placeholder="输入你的消息...">
        <button onclick="sendMessage()">发送</button>
    </div>

    <script>
        const PROXY_URL = 'https://your-worker.workers.dev';
        const PROXY_KEY = 'your-proxy-key';

        async function sendMessage() {
            const input = document.getElementById('user-input');
            const message = input.value.trim();
            
            if (!message) return;
            
            // 添加用户消息到聊天
            addMessage('user', message);
            input.value = '';
            
            try {
                const response = await fetch(`${PROXY_URL}/chat`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${PROXY_KEY}`
                    },
                    body: JSON.stringify({
                        model: 'deepseek-chat',
                        messages: [
                            { role: 'user', content: message }
                        ]
                    })
                });

                if (!response.ok) {
                    throw new Error(`HTTP 错误! 状态: ${response.status}`);
                }

                const data = await response.json();
                addMessage('assistant', data.choices[0].message.content);
                
            } catch (error) {
                console.error('错误:', error);
                addMessage('error', '获取 AI 响应失败');
            }
        }

        function addMessage(role, content) {
            const messages = document.getElementById('messages');
            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${role}`;
            messageDiv.textContent = `${role}: ${content}`;
            messages.appendChild(messageDiv);
            messages.scrollTop = messages.scrollHeight;
        }

        // 允许使用回车键发送消息
        document.getElementById('user-input').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                sendMessage();
            }
        });
    </script>

    <style>
        #chat-container {
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
        }
        
        #messages {
            height: 400px;
            overflow-y: auto;
            border: 1px solid #ccc;
            padding: 10px;
            margin-bottom: 10px;
            background-color: #f9f9f9;
        }
        
        .message {
            margin-bottom: 10px;
            padding: 5px;
            border-radius: 5px;
        }
        
        .message.user {
            background-color: #e3f2fd;
            text-align: right;
        }
        
        .message.assistant {
            background-color: #f3e5f5;
        }
        
        .message.error {
            background-color: #ffebee;
            color: #c62828;
        }
        
        #user-input {
            width: 70%;
            padding: 10px;
            margin-right: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
        }
        
        button {
            padding: 10px 20px;
            background-color: #2196f3;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        
        button:hover {
            background-color: #1976d2;
        }
    </style>
</body>
</html>

React.js

支持流式响应的 React 组件:

import React, { useState, useEffect } from 'react';

const PROXY_URL = 'https://your-worker.workers.dev';
const PROXY_KEY = 'your-proxy-key';

function ChatComponent() {
    const [messages, setMessages] = useState([]);
    const [input, setInput] = useState('');
    const [isLoading, setIsLoading] = useState(false);

    const sendMessage = async () => {
        if (!input.trim()) return;

        const userMessage = { role: 'user', content: input };
        setMessages(prev => [...prev, userMessage]);
        setInput('');
        setIsLoading(true);

        try {
            const response = await fetch(`${PROXY_URL}/chat`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${PROXY_KEY}`,
                    'Accept': 'text/event-stream'
                },
                body: JSON.stringify({
                    model: 'deepseek-chat',
                    messages: [...messages, userMessage],
                    stream: true
                })
            });

            if (!response.ok) {
                throw new Error(`HTTP 错误! 状态: ${response.status}`);
            }

            // 处理流式响应
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let assistantMessage = { role: 'assistant', content: '' };
            
            setMessages(prev => [...prev, assistantMessage]);

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                const chunk = decoder.decode(value);
                const lines = chunk.split('\n');

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const data = line.slice(6);
                        if (data === '[DONE]') continue;

                        try {
                            const parsed = JSON.parse(data);
                            const content = parsed.choices?.[0]?.delta?.content || '';
                            
                            if (content) {
                                setMessages(prev => {
                                    const updated = [...prev];
                                    updated[updated.length - 1].content += content;
                                    return updated;
                                });
                            }
                        } catch (e) {
                            console.error('解析块错误:', e);
                        }
                    }
                }
            }

        } catch (error) {
            console.error('错误:', error);
            setMessages(prev => [...prev, { 
                role: 'error', 
                content: '获取 AI 响应失败' 
            }]);
        } finally {
            setIsLoading(false);
        }
    };

    return (
        <div className="chat-container">
            <div className="messages">
                {messages.map((message, index) => (
                    <div key={index} className={`message ${message.role}`}>
                        <strong>{message.role === 'user' ? '用户' : message.role === 'assistant' ? '助手' : '错误'}:</strong> {message.content}
                    </div>
                ))}
                {isLoading && <div className="loading">AI 正在思考...</div>}
            </div>
            
            <div className="input-container">
                <input
                    type="text"
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
                    placeholder="输入你的消息..."
                    disabled={isLoading}
                />
                <button onClick={sendMessage} disabled={isLoading}>
                    发送
                </button>
            </div>
        </div>
    );
}

export default ChatComponent;

Vue.js

Vue 3 组合式 API 示例:

<template>
  <div class="chat-container">
    <div class="messages" ref="messagesContainer">
      <div 
        v-for="(message, index) in messages" 
        :key="index" 
        :class="`message ${message.role}`"
      >
        <strong>{{ getRoleText(message.role) }}:</strong> {{ message.content }}
      </div>
      <div v-if="isLoading" class="loading">AI 正在思考...</div>
    </div>
    
    <div class="input-container">
      <input
        v-model="input"
        @keypress.enter="sendMessage"
        placeholder="输入你的消息..."
        :disabled="isLoading"
      />
      <button @click="sendMessage" :disabled="isLoading">
        发送
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted } from 'vue';

const PROXY_URL = 'https://your-worker.workers.dev';
const PROXY_KEY = 'your-proxy-key';

const messages = ref([]);
const input = ref('');
const isLoading = ref(false);
const messagesContainer = ref(null);

const getRoleText = (role) => {
  switch (role) {
    case 'user': return '用户';
    case 'assistant': return '助手';
    case 'error': return '错误';
    default: return role;
  }
};

const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
  });
};

const sendMessage = async () => {
  if (!input.value.trim()) return;

  const userMessage = { role: 'user', content: input.value };
  messages.value.push(userMessage);
  input.value = '';
  isLoading.value = true;
  scrollToBottom();

  try {
    const response = await fetch(`${PROXY_URL}/chat`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${PROXY_KEY}`
      },
      body: JSON.stringify({
        model: 'deepseek-chat',
        messages: messages.value
      })
    });

    if (!response.ok) {
      throw new Error(`HTTP 错误! 状态: ${response.status}`);
    }

    const data = await response.json();
    messages.value.push({
      role: 'assistant',
      content: data.choices[0].message.content
    });
    
    scrollToBottom();

  } catch (error) {
    console.error('错误:', error);
    messages.value.push({
      role: 'error',
      content: '获取 AI 响应失败'
    });
  } finally {
    isLoading.value = false;
  }
};

onMounted(() => {
  // 添加欢迎消息
  messages.value.push({
    role: 'assistant',
    content: '你好!我是你的 AI 助手。今天我能为你做些什么?'
  });
});
</script>

<style scoped>
.chat-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

.messages {
  height: 400px;
  overflow-y: auto;
  border: 1px solid #ccc;
  padding: 10px;
  margin-bottom: 10px;
  background-color: #f9f9f9;
}

.message {
  margin-bottom: 10px;
  padding: 8px;
  border-radius: 4px;
}

.message.user {
  background-color: #e3f2fd;
  text-align: right;
}

.message.assistant {
  background-color: #f3e5f5;
}

.message.error {
  background-color: #ffebee;
  color: #c62828;
}

.loading {
  font-style: italic;
  color: #666;
  text-align: center;
}

.input-container {
  display: flex;
  gap: 10px;
}

input {
  flex: 1;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

button {
  padding: 10px 20px;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover:not(:disabled) {
  background-color: #1976d2;
}

button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}
</style>

📱 移动应用

iOS (Swift)

使用 async/await 的 Swift 实现:

import Foundation

class AIProxyService {
    private let proxyURL = "https://your-worker.workers.dev"
    private let proxyKey = "your-proxy-key"
    
    struct ChatRequest: Codable {
        let model: String
        let messages: [Message]
        let stream: Bool?
    }
    
    struct Message: Codable {
        let role: String
        let content: String
    }
    
    struct ChatResponse: Codable {
        let choices: [Choice]
    }
    
    struct Choice: Codable {
        let message: Message
    }
    
    func sendMessage(_ messages: [Message]) async throws -> String {
        guard let url = URL(string: "\(proxyURL)/chat") else {
            throw URLError(.badURL)
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("Bearer \(proxyKey)", forHTTPHeaderField: "Authorization")
        
        let chatRequest = ChatRequest(
            model: "deepseek-chat",
            messages: messages,
            stream: false
        )
        
        request.httpBody = try JSONEncoder().encode(chatRequest)
        
        let (data, response) = try await URLSession.shared.data(for: request)
        
        guard let httpResponse = response as? HTTPURLResponse,
              httpResponse.statusCode == 200 else {
            throw URLError(.badServerResponse)
        }
        
        let chatResponse = try JSONDecoder().decode(ChatResponse.self, from: data)
        return chatResponse.choices.first?.message.content ?? ""
    }
}

// SwiftUI 视图中的使用
import SwiftUI

struct ChatView: View {
    @State private var messages: [AIProxyService.Message] = []
    @State private var inputText = ""
    @State private var isLoading = false
    
    private let aiService = AIProxyService()
    
    var body: some View {
        VStack {
            ScrollView {
                LazyVStack(alignment: .leading, spacing: 10) {
                    ForEach(messages.indices, id: \.self) { index in
                        MessageBubble(message: messages[index])
                    }
                    
                    if isLoading {
                        HStack {
                            ProgressView()
                                .scaleEffect(0.8)
                            Text("AI 正在思考...")
                                .foregroundColor(.secondary)
                        }
                        .padding()
                    }
                }
            }
            
            HStack {
                TextField("输入你的消息...", text: $inputText)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .disabled(isLoading)
                
                Button("发送") {
                    Task {
                        await sendMessage()
                    }
                }
                .disabled(inputText.isEmpty || isLoading)
            }
            .padding()
        }
        .navigationTitle("AI 聊天")
    }
    
    private func sendMessage() async {
        let userMessage = AIProxyService.Message(role: "user", content: inputText)
        messages.append(userMessage)
        
        let currentInput = inputText
        inputText = ""
        isLoading = true
        
        do {
            let response = try await aiService.sendMessage(messages)
            let assistantMessage = AIProxyService.Message(role: "assistant", content: response)
            messages.append(assistantMessage)
        } catch {
            let errorMessage = AIProxyService.Message(role: "error", content: "获取响应失败: \(error.localizedDescription)")
            messages.append(errorMessage)
        }
        
        isLoading = false
    }
}

struct MessageBubble: View {
    let message: AIProxyService.Message
    
    var body: some View {
        HStack {
            if message.role == "user" {
                Spacer()
            }
            
            VStack(alignment: .leading) {
                Text(getRoleText(message.role))
                    .font(.caption)
                    .foregroundColor(.secondary)
                
                Text(message.content)
                    .padding()
                    .background(backgroundColor)
                    .cornerRadius(10)
            }
            
            if message.role == "assistant" || message.role == "error" {
                Spacer()
            }
        }
        .padding(.horizontal)
    }
    
    private func getRoleText(_ role: String) -> String {
        switch role {
        case "user": return "用户"
        case "assistant": return "助手"
        case "error": return "错误"
        default: return role
        }
    }
    
    private var backgroundColor: Color {
        switch message.role {
        case "user":
            return .blue.opacity(0.2)
        case "assistant":
            return .purple.opacity(0.2)
        case "error":
            return .red.opacity(0.2)
        default:
            return .gray.opacity(0.2)
        }
    }
}

🖥️ 桌面应用

Python

使用 tkinter 的 Python 桌面应用:

import tkinter as tk
from tkinter import scrolledtext, messagebox
import requests
import json
import threading
from typing import List, Dict

class AIProxyClient:
    def __init__(self, proxy_url: str, proxy_key: str):
        self.proxy_url = proxy_url
        self.proxy_key = proxy_key
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {proxy_key}',
            'Content-Type': 'application/json'
        })
    
    def send_message(self, messages: List[Dict[str, str]]) -> str:
        try:
            response = self.session.post(
                f'{self.proxy_url}/chat',
                json={
                    'model': 'deepseek-chat',
                    'messages': messages
                },
                timeout=30
            )
            response.raise_for_status()
            
            data = response.json()
            return data['choices'][0]['message']['content']
            
        except requests.exceptions.RequestException as e:
            raise Exception(f"请求失败: {str(e)}")
        except (KeyError, IndexError) as e:
            raise Exception(f"无效的响应格式: {str(e)}")

class ChatGUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("AI 聊天助手")
        self.root.geometry("600x500")
        
        # 初始化 AI 客户端
        self.ai_client = AIProxyClient(
            proxy_url="https://your-worker.workers.dev",
            proxy_key="your-proxy-key"
        )
        
        self.messages = []
        self.setup_ui()
        
    def setup_ui(self):
        # 聊天显示区域
        self.chat_display = scrolledtext.ScrolledText(
            self.root,
            wrap=tk.WORD,
            state=tk.DISABLED,
            height=20,
            font=('微软雅黑', 10)
        )
        self.chat_display.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 输入框架
        input_frame = tk.Frame(self.root)
        input_frame.pack(fill=tk.X, padx=10, pady=5)
        
        # 消息输入
        self.message_entry = tk.Entry(input_frame, font=('微软雅黑', 10))
        self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        self.message_entry.bind('<Return>', self.send_message)
        
        # 发送按钮
        self.send_button = tk.Button(
            input_frame,
            text="发送",
            command=self.send_message,
            font=('微软雅黑', 10),
            bg='#2196f3',
            fg='white',
            relief=tk.FLAT,
            padx=20
        )
        self.send_button.pack(side=tk.RIGHT)
        
        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set("就绪")
        status_bar = tk.Label(
            self.root,
            textvariable=self.status_var,
            relief=tk.SUNKEN,
            anchor=tk.W
        )
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
        # 添加欢迎消息
        self.add_message("assistant", "你好!我是你的 AI 助手。今天我能为你做些什么?")
    
    def add_message(self, role: str, content: str):
        self.chat_display.config(state=tk.NORMAL)
        
        # 添加角色标签
        role_text = {"user": "用户", "assistant": "助手", "error": "错误"}.get(role, role)
        self.chat_display.insert(tk.END, f"{role_text}: ", f"{role}_label")
        
        # 添加消息内容
        self.chat_display.insert(tk.END, f"{content}\n\n")
        
        # 配置标签样式
        self.chat_display.tag_config("user_label", foreground="blue", font=('微软雅黑', 10, 'bold'))
        self.chat_display.tag_config("assistant_label", foreground="purple", font=('微软雅黑', 10, 'bold'))
        self.chat_display.tag_config("error_label", foreground="red", font=('微软雅黑', 10, 'bold'))
        
        self.chat_display.config(state=tk.DISABLED)
        self.chat_display.see(tk.END)
    
    def send_message(self, event=None):
        message = self.message_entry.get().strip()
        if not message:
            return
        
        # 添加用户消息
        self.add_message("user", message)
        self.messages.append({"role": "user", "content": message})
        
        # 清空输入
        self.message_entry.delete(0, tk.END)
        
        # 禁用发送按钮并显示加载状态
        self.send_button.config(state=tk.DISABLED)
        self.status_var.set("AI 正在思考...")
        
        # 在后台线程中发送请求
        threading.Thread(target=self.get_ai_response, daemon=True).start()
    
    def get_ai_response(self):
        try:
            response = self.ai_client.send_message(self.messages)
            
            # 在主线程中更新 UI
            self.root.after(0, lambda: self.handle_ai_response(response))
            
        except Exception as e:
            error_msg = f"错误: {str(e)}"
            self.root.after(0, lambda: self.handle_error(error_msg))
    
    def handle_ai_response(self, response: str):
        self.add_message("assistant", response)
        self.messages.append({"role": "assistant", "content": response})
        
        # 重新启用发送按钮
        self.send_button.config(state=tk.NORMAL)
        self.status_var.set("就绪")
        self.message_entry.focus()
    
    def handle_error(self, error_msg: str):
        self.add_message("error", error_msg)
        
        # 重新启用发送按钮
        self.send_button.config(state=tk.NORMAL)
        self.status_var.set("就绪")
        self.message_entry.focus()
    
    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    app = ChatGUI()
    app.run()

🔧 后端集成

Node.js/Express

用于代理 AI 请求的 Express 中间件:

const express = require('express');
const fetch = require('node-fetch');

const app = express();
app.use(express.json());

const PROXY_URL = 'https://your-worker.workers.dev';
const PROXY_KEY = 'your-proxy-key';

// 代理 AI 请求的中间件
app.post('/api/chat', async (req, res) => {
    try {
        const response = await fetch(`${PROXY_URL}/chat`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${PROXY_KEY}`
            },
            body: JSON.stringify(req.body)
        });

        if (!response.ok) {
            throw new Error(`代理错误: ${response.status} ${response.statusText}`);
        }

        const data = await response.json();
        res.json(data);

    } catch (error) {
        console.error('AI 代理错误:', error);
        res.status(500).json({
            error: 'ai_proxy_error',
            message: '获取 AI 响应失败'
        });
    }
});

// 健康检查端点
app.get('/api/health', (req, res) => {
    res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`服务器运行在端口 ${PORT}`);
});

准备好集成了吗? 🚀

选择最适合你技术栈的示例,并根据你的具体需求进行定制。所有示例都包含适当的错误处理,可以扩展更多功能,如对话历史、用户认证等。