mixvideo-v2/cargos/gemini-sdk/promptx.md

14 KiB
Raw Blame History

Gemini SDK 开发提示词

项目概述

基于 apps\desktop\src-tauri\src\infrastructure\gemini_service.rs 的现有实现,创建一个独立的 Rust crate gemini-sdk,提供简洁易用的 Gemini AI 服务接口。

核心设计目标

  1. 简化接口: 提供统一的消息发送接口,支持文本+附件输入
  2. Agent 系统: 支持多个 AI Agent每个 Agent 有独立的 system prompt 和配置
  3. 多轮对话: 支持会话管理和历史记录
  4. 类型安全: 强类型设计,编译时错误检查
  5. 易于集成: 最小化外部依赖,易于在其他项目中使用

技术架构

依赖管理

[dependencies]
tokio = { version = "1.0", features = ["full"] }
reqwest = { version = "0.11", features = ["json", "multipart"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
uuid = { version = "1.0", features = ["v4"] }
chrono = { version = "0.4", features = ["serde"] }
base64 = "0.22"
rusqlite = { version = "0.31", features = ["bundled", "chrono"] }

核心数据结构

// SDK 主体
pub struct GeminiSDK {
    service: GeminiService,
    conversation_repo: Option<Arc<ConversationRepository>>,
    agents: HashMap<String, Agent>,
}

// Agent 定义
pub struct Agent {
    pub id: String,
    pub name: String,
    pub system_prompt: String,
    pub config: AgentConfig,
    pub created_at: DateTime<Utc>,
}

pub struct AgentConfig {
    pub temperature: f32,
    pub max_tokens: u32,
    pub timeout: u64,
    pub enable_conversation: bool,
}

// 消息结构
pub struct MessageRequest {
    pub text: String,
    pub attachments: Vec<Attachment>,
    pub agent_id: Option<String>,
    pub session_id: Option<String>,
    pub config: Option<MessageConfig>,
}

pub struct MessageResponse {
    pub content: String,
    pub session_id: String,
    pub message_id: Option<String>,
    pub agent_id: Option<String>,
}

// 附件定义
pub struct Attachment {
    pub path: String,
    pub mime_type: Option<String>,
}

// 会话管理
pub struct ConversationSession {
    pub session_id: String,
    pub title: Option<String>,
    pub created_at: DateTime<Utc>,
}

pub struct HistoryMessage {
    pub role: MessageRole,
    pub content: String,
    pub timestamp: DateTime<Utc>,
    pub attachments: Vec<String>,
}

核心功能接口

1. SDK 初始化

impl GeminiSDK {
    // 基础初始化
    pub fn new() -> Result<Self>;
    
    // 支持多轮对话
    pub fn with_conversation_support(db_path: Option<String>) -> Result<Self>;
    
    // 自定义配置
    pub fn with_config(config: GeminiConfig) -> Result<Self>;
}

2. 核心消息接口

impl GeminiSDK {
    // 主要方法:发送消息+附件,获得回复
    pub async fn send_message(&mut self, request: MessageRequest) -> Result<MessageResponse>;
}

3. Agent 管理

impl GeminiSDK {
    // Agent CRUD
    pub fn create_agent(&mut self, name: String, system_prompt: String, config: Option<AgentConfig>) -> Result<Agent>;
    pub fn get_agent(&self, agent_id: &str) -> Option<&Agent>;
    pub fn list_agents(&self) -> Vec<&Agent>;
    pub fn update_agent(&mut self, agent_id: &str, name: Option<String>, system_prompt: Option<String>, config: Option<AgentConfig>) -> Result<()>;
    pub fn delete_agent(&mut self, agent_id: &str) -> Result<()>;
    
    // 预设 Agent
    pub fn create_outfit_advisor_agent(&mut self) -> Result<Agent>;
    pub fn create_video_analyst_agent(&mut self) -> Result<Agent>;
    pub fn create_general_assistant_agent(&mut self) -> Result<Agent>;
}

4. 会话管理

impl GeminiSDK {
    // 会话 CRUD
    pub async fn create_session(&self, title: Option<String>) -> Result<ConversationSession>;
    pub async fn get_session(&self, session_id: &str) -> Result<Option<ConversationSession>>;
    pub async fn list_sessions(&self) -> Result<Vec<ConversationSession>>;
    pub async fn delete_session(&self, session_id: &str) -> Result<()>;
    
    // 历史记录
    pub async fn get_conversation_history(&self, session_id: &str, limit: Option<u32>) -> Result<Vec<HistoryMessage>>;
    pub async fn clear_conversation_history(&self, session_id: &str) -> Result<()>;
}

5. 便捷构造函数

impl Attachment {
    pub fn new(path: impl Into<String>) -> Self;
    pub fn with_mime_type(path: impl Into<String>, mime_type: impl Into<String>) -> Self;
}

impl MessageRequest {
    pub fn text_only(text: impl Into<String>) -> Self;
    pub fn with_attachments(text: impl Into<String>, attachments: Vec<Attachment>) -> Self;
    pub fn with_agent(text: impl Into<String>, agent_id: impl Into<String>) -> Self;
}

实现要求

1. 文件结构

cargos/gemini-sdk/
├── Cargo.toml
├── src/
│   ├── lib.rs              # 主入口
│   ├── sdk.rs              # SDK 主体实现
│   ├── agent.rs            # Agent 相关
│   ├── conversation.rs     # 会话管理
│   ├── attachment.rs       # 附件处理
│   ├── error.rs            # 错误定义
│   └── presets/            # 预设 Agent
│       ├── mod.rs
│       ├── outfit_advisor.rs
│       ├── video_analyst.rs
│       └── general_assistant.rs
├── examples/
│   ├── basic_usage.rs
│   ├── agent_demo.rs
│   └── conversation_demo.rs
└── tests/
    ├── integration_tests.rs
    └── agent_tests.rs

2. 核心实现逻辑

消息发送流程

  1. 检查是否指定 Agent获取对应配置和 system prompt
  2. 处理附件:根据文件类型选择上传(视频)或编码(图片)
  3. 构建 Gemini API 请求,包含 system prompt
  4. 如果启用会话,使用多轮对话模式;否则使用单轮模式
  5. 调用底层 GeminiService 方法
  6. 返回格式化的响应

Agent 系统

  1. 内存中维护 Agent 映射表
  2. 每个 Agent 包含独立的 system prompt 和配置
  3. 提供预设的专业 Agent穿搭顾问、视频分析师等
  4. 支持动态创建和管理自定义 Agent

会话管理

  1. 可选的 SQLite 数据库支持
  2. 自动会话创建和历史记录保存
  3. 支持会话标题和元数据管理
  4. 历史消息检索和清理

3. 错误处理

#[derive(Debug, thiserror::Error)]
pub enum SDKError {
    #[error("配置错误: {0}")]
    Config(String),
    
    #[error("Agent 不存在: {0}")]
    AgentNotFound(String),
    
    #[error("会话错误: {0}")]
    Session(String),
    
    #[error("附件处理错误: {0}")]
    Attachment(String),
    
    #[error("网络错误: {0}")]
    Network(#[from] reqwest::Error),
    
    #[error("数据库错误: {0}")]
    Database(#[from] rusqlite::Error),
    
    #[error("Gemini 服务错误: {0}")]
    GeminiService(#[from] anyhow::Error),
}

4. 使用示例

// 基础使用
let mut sdk = GeminiSDK::with_conversation_support(None)?;

// 创建穿搭顾问 Agent
let agent = sdk.create_outfit_advisor_agent()?;

// 发送消息
let request = MessageRequest {
    text: "分析这张穿搭图片".to_string(),
    attachments: vec![Attachment::new("./outfit.jpg")],
    agent_id: Some(agent.id),
    session_id: None,
    config: None,
};

let response = sdk.send_message(request).await?;
println!("回复: {}", response.content);

开发指导

1. 代码复用策略

  • 直接复用 gemini_service.rs 中的核心逻辑
  • 提取通用的配置、错误处理和网络请求代码
  • 简化接口,隐藏内部复杂性

2. 测试策略

  • 单元测试:各个组件的独立功能
  • 集成测试:完整的消息发送流程
  • 示例代码:展示各种使用场景

3. 文档要求

  • 完整的 API 文档
  • 使用示例和最佳实践
  • 错误处理指南
  • 性能优化建议

4. 性能考虑

  • 连接池复用
  • 合理的超时设置
  • 内存使用优化
  • 异步操作支持

交付标准

  1. 功能完整性: 所有设计的接口都能正常工作
  2. 代码质量: 遵循 Rust 最佳实践,通过 clippy 检查
  3. 测试覆盖: 核心功能有完整的测试覆盖
  4. 文档完善: 清晰的 API 文档和使用示例
  5. 易用性: 简洁的接口,最小化学习成本

详细实现指南

1. 从现有代码迁移的关键组件

需要复用的核心结构

// 从 gemini_service.rs 复用
pub struct GeminiConfig { /* 保持原有字段 */ }
pub struct GenerateContentRequest { /* 保持原有结构 */ }
pub struct ContentPart { /* 保持原有结构 */ }
pub enum Part { /* 保持原有枚举 */ }
pub struct GenerationConfig { /* 保持原有结构 */ }

需要复用的核心方法

  • get_access_token() - 访问令牌管理
  • upload_video_file() - 视频文件上传
  • generate_content_with_request() - 内容生成
  • query_llm_with_grounding_multi_turn() - 多轮对话
  • extract_json_from_response() - JSON 解析

2. 简化的内部服务层

// 简化的内部服务,封装复杂逻辑
struct InternalGeminiService {
    config: GeminiConfig,
    client: reqwest::Client,
    access_token: Option<String>,
    token_expires_at: Option<u64>,
}

impl InternalGeminiService {
    // 复用原有的核心方法,但简化接口
    async fn send_request(&mut self, parts: Vec<Part>, config: GenerationConfig, system_prompt: Option<String>) -> Result<String>;
    async fn upload_file(&mut self, path: &str) -> Result<String>;
    async fn send_multipart_request(&mut self, parts: Vec<Part>, config: GenerationConfig, system_prompt: Option<String>, session_id: Option<String>) -> Result<String>;
}

4. 错误恢复和重试机制

impl GeminiSDK {
    async fn send_message_with_retry(&mut self, request: MessageRequest, max_retries: u32) -> Result<MessageResponse> {
        let mut last_error = None;

        for attempt in 0..max_retries {
            match self.send_message_internal(request.clone()).await {
                Ok(response) => return Ok(response),
                Err(e) => {
                    last_error = Some(e);
                    if attempt < max_retries - 1 {
                        let delay = std::time::Duration::from_secs(2_u64.pow(attempt));
                        tokio::time::sleep(delay).await;
                    }
                }
            }
        }

        Err(last_error.unwrap())
    }
}

5. 配置管理

impl GeminiSDK {
    pub fn from_env() -> Result<Self> {
        let config = GeminiConfig {
            base_url: std::env::var("GEMINI_BASE_URL").unwrap_or_else(|_| "https://bowongai-dev--bowong-ai-video-gemini-fastapi-webapp.modal.run".to_string()),
            bearer_token: std::env::var("GEMINI_BEARER_TOKEN").unwrap_or_else(|_| "bowong7777".to_string()),
            // ... 其他配置
        };

        Self::with_config(config)
    }
}

6. 完整的使用示例

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 初始化 SDK
    let mut sdk = GeminiSDK::with_conversation_support(None)?;


    // 3. 穿搭分析示例
    let outfit_request = MessageRequest {
        text: "请分析这张穿搭图片,给出专业的搭配建议".to_string(),
        attachments: vec![Attachment::new("./examples/outfit.jpg")],
        agent_id: Some(outfit_agent.id.clone()),
        session_id: None,
        config: None,
    };

    let outfit_response = sdk.send_message(outfit_request).await?;
    println!("穿搭顾问分析:\n{}", outfit_response.content);

    // 4. 视频分析示例
    let video_request = MessageRequest {
        text: "请分析这个视频的内容质量和改进建议".to_string(),
        attachments: vec![Attachment::new("./examples/video.mp4")],
        agent_id: Some(video_agent.id),
        session_id: None,
        config: Some(MessageConfig {
            temperature: Some(0.6),
            max_tokens: Some(12000),
            timeout: Some(180),
        }),
    };

    let video_response = sdk.send_message(video_request).await?;
    println!("视频分析报告:\n{}", video_response.content);

    // 5. 多轮对话示例
    let session = sdk.create_session(Some("穿搭咨询".to_string())).await?;

    let follow_up = MessageRequest {
        text: "基于刚才的分析,我想要更正式一些的搭配方案".to_string(),
        attachments: vec![],
        agent_id: Some(outfit_agent.id),
        session_id: Some(session.session_id.clone()),
        config: None,
    };

    let follow_response = sdk.send_message(follow_up).await?;
    println!("后续建议:\n{}", follow_response.content);

    // 6. 查看对话历史
    let history = sdk.get_conversation_history(&session.session_id, Some(10)).await?;
    for msg in history {
        println!("{}: {}", msg.role, msg.content);
    }

    Ok(())
}

质量保证要求

1. 代码规范

  • 使用 cargo fmt 格式化代码
  • 通过 cargo clippy 静态检查
  • 添加适当的文档注释
  • 遵循 Rust 命名约定

2. 测试要求

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

    #[tokio::test]
    async fn test_basic_message_sending() {
        // 测试基础消息发送功能
    }

    #[tokio::test]
    async fn test_agent_management() {
        // 测试 Agent 创建和管理
    }

    #[tokio::test]
    async fn test_conversation_flow() {
        // 测试多轮对话流程
    }

    #[tokio::test]
    async fn test_attachment_processing() {
        // 测试附件处理
    }
}

3. 文档要求

  • 每个公共接口都要有详细的文档注释
  • 提供完整的使用示例
  • 包含错误处理指南
  • 性能和最佳实践说明

请基于这个详细的设计方案和实现指南,创建一个高质量、易用、功能完整的 Gemini SDK crate。