Files
DevFlow/docs/03-模块文档/df-ai-AI集成模块.md
绝尘 98393b4908 新增: 初始化 DevFlow 项目仓库
Tauri 2 + Vue 3 + Vite 6 桌面应用,Rust workspace 含 13 个 crate
(df-ai / df-storage / df-workflow / df-core / df-execute 等)。
核心能力:AI 聊天 agentic 循环(工具调用+人工审批)、工作流引擎、
任务/想法/项目/阶段管理、可追溯性,及配套前端组件。
2026-06-12 01:31:05 +08:00

6.6 KiB
Raw Blame History

df-ai - AI 集成模块

Provider 抽象层与流式响应处理

📋 模块概览

df-ai 负责 AI 功能的核心集成,支持多个 AI Provider提供统一的接口和流式响应处理。

主要特性

  • 多 Provider 支持OpenAI、Anthropic、DeepSeek
  • 流式响应处理
  • 工具调用支持
  • 错误处理和重试机制

🏗️ 架构设计

核心组件

// Provider trait 定义
pub trait AIProvider: Send + Sync {
    async fn chat_completion(&self, request: ChatRequest) -> Result<ChatResponse>;
    async fn create_embedding(&self, text: &str) -> Result<Vec<f32>>;
}

// 流式响应处理
pub struct StreamProcessor {
    event_sender: mpsc::UnboundedSender<StreamEvent>,
}

// 统一的 AI 服务
pub struct AIService {
    providers: HashMap<String, Box<dyn AIProvider>>,
    default_provider: String,
}

Provider 实现

  • OpenAIProvider: OpenAI GPT 系列模型
  • AnthropicProvider: Claude 系列模型
  • DeepSeekProvider: DeepSeek 模型

🔧 使用方法

基础聊天

use df_ai::AIService;

let ai_service = AIService::new(config);
let request = ChatRequest {
    model: "gpt-4".to_string(),
    messages: vec![Message {
        role: "user".to_string(),
        content: "Hello, world!".to_string(),
    }],
};

let response = ai_service.chat_completion(request).await?;

流式响应

use df_ai::stream_chat;

let (mut receiver, mut stream) = stream_chat(&ai_service, request).await?;

while let Some(event) = receiver.recv().await {
    match event {
        StreamEvent::Content(chunk) => {
            print!("{}", chunk);
        }
        StreamEvent::Done => {
            println!("\n完成");
        }
        StreamEvent::Error(e) => {
            eprintln!("错误: {}", e);
        }
    }
}

工具调用

let request = ChatRequest {
    model: "gpt-4".to_string(),
    messages: vec![Message {
        role: "user".to_string(),
        content: "创建一个文件".to_string(),
    }],
    tools: vec![Tool {
        r#type: "function".to_string(),
        function: FunctionDef {
            name: "create_file".to_string(),
            description: "创建文件".to_string(),
            parameters: Parameters {
                r#type: "object".to_string(),
                properties: serde_json::json!({
                    "path": {"type": "string"},
                    "content": {"type": "string"}
                }),
                required: vec!["path".to_string()],
            },
        },
    }],
    tool_choice: "auto".to_string(),
};

⚙️ 配置

Provider 配置

# config/ai.yaml
providers:
  openai:
    api_key: ${OPENAI_API_KEY}
    base_url: "https://api.openai.com/v1"
    model: "gpt-4"
    max_tokens: 4000
    temperature: 0.7
  
  anthropic:
    api_key: ${ANTHROPIC_API_KEY}
    model: "claude-3-sonnet-20240229"
    max_tokens: 4000
    temperature: 0.7
  
  deepseek:
    api_key: ${DEEPSEEK_API_KEY}
    model: "deepseek-chat"
    max_tokens: 4000
    temperature: 0.7

default_provider: "openai"

环境变量

export OPENAI_API_KEY="sk-your-key"
export ANTHROPIC_API_KEY="sk-ant-key"
export DEEPSEEK_API_KEY="your-key"

🔄 错误处理

错误类型

pub enum AIError {
    APIError(String),           // API 调用失败
    Timeout,                   // 请求超时
    RateLimit,                 // 达到速率限制
    InvalidResponse,          // 响应格式错误
    ProviderNotFound,         // Provider 不存在
    ConfigurationError,      // 配置错误
}

重试机制

let config = RetryConfig {
    max_attempts: 3,
    backoff: ExponentialBackoff::from_millis(1000),
    retryable_errors: vec![
        AIError::Timeout,
        AIError::RateLimit,
    ],
};

let response = ai_service.chat_with_retry(request, &config).await?;

📊 性能优化

缓存机制

pub struct CachedAIService {
    inner: AIService,
    cache: Arc<Mutex<HashMap<String, ChatResponse>>>,
}

// 缓存键生成
fn cache_key(request: &ChatRequest) -> String {
    format!("{:?}-{:?}", request.model, request.messages)
}

连接池

pub struct ConnectionPool {
    connections: HashMap<String, Vec<Client>>,
    max_connections: usize,
}

pub async fn get_client(&self, provider: &str) -> Result<Client> {
    // 从连接池获取或创建新连接
}

🔍 监控与日志

请求追踪

pub struct RequestTracer {
    request_id: String,
    start_time: Instant,
    metrics: RequestMetrics,
}

impl RequestTracer {
    pub fn log_request(&self, provider: &str, duration: Duration) {
        metrics.record_request(provider, duration);
    }
}

指标收集

pub struct RequestMetrics {
    total_requests: AtomicU64,
    successful_requests: AtomicU64,
    failed_requests: AtomicU64,
    average_duration: AtomicDuration,
}

🧪 测试

单元测试

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_chat_completion() {
        let ai_service = AIService::new(test_config());
        let request = test_request();
        let response = ai_service.chat_completion(request).await;
        assert!(response.is_ok());
    }
}

集成测试

#[tokio::test]
async fn test_multiple_providers() {
    let providers = vec!["openai", "anthropic"];
    for provider in providers {
        let ai_service = AIService::new(config_for_provider(provider));
        let response = test_chat(&ai_service).await;
        assert!(response.is_ok(), "Provider {} failed", provider);
    }
}

🚨 最佳实践

1. 错误处理

// ✅ 正确
match ai_service.chat_completion(request).await {
    Ok(response) => handle_response(response),
    Err(AIError::RateLimit) => wait_and_retry(),
    Err(e) => log_error_and_notify(e),
}

// ❌ 错误 - 忽略错误
let _ = ai_service.chat_completion(request).await;

2. 资源管理

// ✅ 正确 - 使用连接池
let client = connection_pool.get_client("openai").await?;

// ❌ 错误 - 每次创建新连接
let client = Client::new(config);

3. 并发控制

// ✅ 正确 - 使用信号量
let semaphore = Arc::new(Semaphore::new(10));
let permit = semaphore.acquire().await?;
let response = ai_service.chat_completion(request).await;

// ❌ 错误 - 无限制并发
let handles: Vec<_> = requests.into_iter().map(|req| {
    tokio::spawn(ai_service.chat_completion(req))
}).collect();

相关文档: