mthoutai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Flutter+Riverpod+MVI架构实践:构建一个安全、高效的跨平台AI提示词优化工具

在AI应用开发浪潮中,如何将复杂的业务逻辑与优雅的用户体验相结合,是每一位开发者面临的挑战。本文将以一个开源的跨平台「AI提示词优化工具」为例,深入剖析如何运用Flutter、Riverpod与MVI架构,构建一个兼顾功能、性能与安全性的现代化应用。这不仅是一次技术实践,更是对现代后端架构思想在前端/跨端领域应用的深度探索。

一、项目缘起:解决AI提示词优化的核心痛点

随着大语言模型(LLM)的普及,提示词(Prompt)的质量直接决定了AI交互的成败。然而,许多开发者和普通用户在实践中遇到了几个普遍难题:

  • 效果不稳定:同一需求的不同表述,可能导致AI回答质量天差地别。
  • 优化效率低下:手动反复调整提示词,过程枯燥且耗时。
  • 数据安全隐忧:API密钥、历史对话等敏感信息如何安全存储与管理?

PromptOptimizer项目正是为解决这些痛点而生。它旨在为用户提供一个专业的工具,通过智能化的方式优化用户指令和系统角色设定,从而显著提升与AI的沟通效率。其核心目标可以概括为:

核心功能具体体现
提效工具一键优化提示词,支持多种优化模板,实时预览结果
跨平台体验Android / iOS / Web / Windows / macOS / Linux 无缝切换
数据安全AES-256 加密存储 API 密钥,本地数据库管理
开发友好开源代码,清晰架构,易于二次开发和定制
完全免费无付费功能,无广告,无数据上传

项目提供了便捷的在线体验和客户端下载入口,方便不同平台的用户使用:

一个基于 Flutter + Riverpod 的开源项目,用 MVI 架构优雅地解决提示词优化实例

有条件的记得使用自己的 Api key 呀!

其界面设计兼顾了美观与实用性,支持浅色与深色模式以适应不同用户的偏好:

请添加图片描述请添加图片描述

二、功能架构设计:以用户为中心的多维度支持

一个优秀工具的背后,必然是清晰的功能架构。本项目从实际应用场景出发,设计了以下核心功能模块:

1. 双模式优化引擎
工具区分了“用户提示词优化”与“系统提示词优化”两种模式。前者专注于优化你给AI的具体指令,使其更清晰、更具操作性;后者则用于优化AI的系统角色设定,帮助AI更好地扮演专家、助手等特定身份,这本质上是在设计一个高效的API交互前端。

2. 灵活的多API支持与安全管理
为了兼容不同的服务端资源,工具集成了对多个主流AI提供商的支持,并设计了安全的密钥管理方案:

提供商API 地址默认模型适用场景
OpenAIapi.openai.comgpt-4o通用、高质量
DashScope(阿里)dashscope.aliyuncs.comqwen-max国内用户首选
DeepSeekapi.deepseek.comdeepseek-chat性价比高
Moonshot(月之暗面)api.moonshot.cnmoonshot-v1-8k长文本处理
Zhipu AI(智谱)open.bigmodel.cnglm-4中文优化
Baidu(文心一言)aip.baidubce.comernie-4.0-8k国内服务
Tencent(混元)hunyuan.tencentcloudapi.comhunyuan-lite腾讯生态
OpenRouter(聚合)openrouter.aillama-3.1-8b模型丰富

其关键特性包括支持OpenAI兼容的自定义端点,以及使用AES-256加密算法在本地安全存储API密钥,避免了密钥明文传输和存储的风险。

3. 模板化与数据管理
为了提高复用性,工具内置了模板管理系统。用户可以保存成功的提示词为模板,方便下次快速调用。模板的定义清晰且灵活:

内置 4 个专业模板:
├──  标准优化模板
├──  学术论文模板
├──  商务文案模板
└──  技术文档模板
+ 自定义模板支持
  └── 使用 {{originalPrompt}} 占位符

例如,一个“代码评审专家”的模板可能这样定义:

【标准优化模板】
请优化以下提示词,使其更清晰、更具体、更容易被 AI 理解:
{{originalPrompt}}
优化要求:
1. 明确目标和预期输出
2. 提供必要的背景信息
3. 指定输出格式
4. 添加约束条件

此外,工具支持数据的导入与导出,方便用户在不同设备间迁移配置和历史记录,这体现了对用户数据资产的尊重:

一键备份:
├── API 配置
├── 自定义模板
├── 优化历史
└── UI 偏好设置
支持格式:
├── PC 端:文件夹选择
└── 移动端:系统分享
[AFFILIATE_SLOT_1]

三、技术架构深度解析:MVI与Riverpod的优雅结合

为了实现上述复杂功能并保证代码的可维护性,项目采用了MVI(Model-View-Intent)架构与Riverpod状态管理的组合。这套组合拳有效管理了应用状态,并实现了清晰的数据流。

1. MVI架构与单向数据流
MVI强制实现了单向数据流(View -> Intent -> Model -> View),使得状态变化可预测、易调试。在Flutter中,我们通常这样实现MVI的各个部分:

┌──────────────┐
│   UI Layer   │ ← 用户交互(点击、输入)
│  (Widget)    │
└──────┬───────┘
       │ 发送 Intent
       ↓
┌──────────────────────┐
│  Intent Handler      │ ← 业务逻辑处理
│  (Notifier)          │
└──────┬───────────────┘
       │ 更新 State
       ↓
┌──────────────────────┐
│  Model (State)       │ ← 数据模型
│  (Freezed)           │
└──────┬───────────────┘
       │ 通知 UI 更新
       ↓
┌──────────────┐
│   UI Layer   │ ← 重新渲染
│  (Widget)    │
└──────────────┘

选择MVI架构主要基于以下几点优势,这些优势在构建复杂交互的微服务前端时同样至关重要:

特点优势
单向数据流数据流向清晰,易于调试
Intent 明确每个用户操作都有对应的 Intent
State 不可变使用 Freezed,避免意外修改
易于测试Intent → State 的映射易于单元测试

2. Riverpod:现代化状态管理的利器
Riverpod作为Provider的继承者,提供了编译时安全、灵活的依赖管理和优异的性能。在本项目中,它被用于连接MVI的各个部分,管理全局和局部状态。一个典型的Riverpod Provider定义如下:

// 定义一个优化 Intent
class OptimizeIntent {
final String originalPrompt;
final String templateId;
final String apiConfigId;
}
// Notifier 处理 Intent
class OptimizationNotifier extends StateNotifier<OptimizationState> {
  OptimizationNotifier() : super(OptimizationState.initial());
  // 处理优化 Intent
  Future<void> optimize(OptimizeIntent intent) async {
    state = state.copyWith(isLoading: true);
    try {
    final result = await _apiService.optimize(intent);
    state = state.copyWith(
    result: result,
    isLoading: false,
    );
    } catch (e) {
    state = state.copyWith(error: e.toString(), isLoading: false);
    }
    }
    }
    // UI 层监听状态
    
    Widget build(BuildContext context, WidgetRef ref) {
    final state = ref.watch(optimizationProvider);
    return state.when(
    loading: () => LoadingWidget(),
    data: (result) => ResultWidget(result),
    error: (error) => ErrorWidget(error),
    );
    }

Riverpod的优势在于其@riverpod注解带来的自动代码生成、精细化的重建控制(通过`select`)以及易于测试的依赖注入机制,这为构建健壮的后端架构支撑的前端应用奠定了基础。

3. 数据持久层设计:Drift + Hive
对于本地数据存储,项目采用了Drift(基于SQLite的ORM)与Hive(轻量级KV数据库)的组合方案:

┌─────────────────────────────────────┐
│         数据存储层                   │
├─────────────────────────────────────┤
│  Drift (SQLite)                     │
│  ├── api_configs 表                 │
│  ├── prompt_templates 表            │
│  └── optimization_histories 表      │
│                                     │
│  Hive (KV 存储)                     │
│  ├── app_settings Box               │
│  │   ├── themeMode                  │
│  │   └── locale                     │
│  └── 其他偏好设置                   │
└─────────────────────────────────────┘

这样的数据库设计策略基于以下考量:

存储方案用途原因
DriftAPI 配置、模板、历史结构化数据,需要复杂查询
HiveUI 偏好设置简单 KV 数据,快速读写

四、核心安全与工程化实践

对于涉及API密钥和用户历史记录的工具,安全性和工程化水平直接决定了产品的可信度。

1. AES-256加密存储
为确保API密钥等敏感信息的安全,项目实现了AES-256加密服务。密钥由用户自定义的主密码派生,且永远不会离开设备本地。加密服务的核心抽象和实现示例如下:

API 密钥存储流程:
┌──────────────────┐
│  用户输入密钥     │
└────────┬─────────┘
         │
         ↓
┌──────────────────┐
│  AES-256 加密    │
│  (256-bit key)   │
└────────┬─────────┘
         │
         ↓
┌──────────────────┐
│  Base64 编码     │
└────────┬─────────┘
         │
         ↓
┌──────────────────┐
│  存储到数据库     │
└──────────────────┘
使用时反向解密:
数据库 → Base64 解码 → AES-256 解密 → 获得原始密钥
class AesCryptoService {
static const String _encryptionKey = 'your-256-bit-key-here';
// 加密
static String encrypt(String plaintext) {
final key = Key.fromUtf8(_encryptionKey);
final iv = IV.fromSecureRandom(16);
final cipher = Encrypter(AES(key, mode: AESMode.cbc));
final encrypted = cipher.encrypt(plaintext, iv: iv);
return '${iv.base64}:${encrypted.base64}';
}
// 解密
static String decrypt(String encrypted) {
final parts = encrypted.split(':');
final iv = IV.fromBase64(parts[0]);
final cipher = Encrypter(AES(Key.fromUtf8(_encryptionKey), mode: AESMode.cbc));
return cipher.decrypt64(parts[1], iv: iv);
}
}

2. 流式响应与性能优化
处理AI生成的长文本时,一次性加载会导致界面卡顿。项目采用SSE(Server-Sent Events)进行流式处理,实现内容的增量更新,极大提升了用户体验:

// 接收 SSE 流
final stream = _apiService.optimizeStream(prompt);
// 逐 token 处理
await for (final token in stream) {
state = state.copyWith(
result: state.result + token, // 增量拼接
);
}

3. 自动化CI/CD流水线
项目使用GitHub Actions实现了完整的CI/CD流程,确保代码质量与构建部署的自动化,这是现代服务端和前端工程的标准实践:

┌─────────────────────────────────────┐
│  Git 推送                            │
├─────────────────────────────────────┤
│  分支推送 (main)                    │
│  └── 代码分析 + Debug 构建          │
│                                     │
│  Tag 推送 (v1.0.0)                  │
│  └── 完整构建 + 自动发布            │
│      ├── Android (APK + AAB)        │
│      ├── Windows (ZIP)              │
│      ├── macOS (ZIP)                │
│      ├── Linux (TAR.GZ)             │
│      └── Web (TAR.GZ)               │
└─────────────────────────────────────┘
[AFFILIATE_SLOT_2]

五、技术亮点与总结

回顾整个项目,以下几个技术亮点值得深入思考和借鉴:

亮点一:清晰的数据流与状态管理
通过MVI+Riverpod,彻底解决了传统`setState`或复杂状态管理库带来的状态混乱问题。状态变更路径清晰,极大地便利了调试和测试:

Intent (用户操作)
  → Notifier (业务逻辑)
  → State (数据模型)
  → UI (重新渲染)

亮点二:模块化与可扩展性
项目在架构上充分考虑了模块化。API支持、加密服务、数据存储等核心模块均被抽象为独立的服务,通过依赖注入连接。这使得添加新的AI提供商或更换加密算法变得非常容易,符合微服务设计中的解耦思想。

亮点三:对开源生态的致敬与贡献
本项目的开发也受到了其他优秀开源项目的启发,并遵循开源精神进行分享:

linshenkx 大佬开发的提示词优化器

请添加图片描述

项目的完整开源地址为:

如果这个项目对你有帮助,请不要忘记给个 ⭐ Star 支持一下!这对我来说意义重大,也是我持续更新的动力

总结
PromptOptimizer项目不仅仅是一个工具,更是一次关于如何运用Flutter、Riverpod、MVI等现代技术栈构建高质量跨平台应用的完整实践。它展示了从需求分析、架构设计、安全加密到工程化部署的全过程。对于开发者而言,其价值不仅在于工具本身的功能,更在于其清晰、可维护、安全的代码架构,为开发复杂的、涉及敏感数据的跨平台应用提供了宝贵的参考范本。无论是处理API集成、数据库设计还是状态管理,这个项目都提供了经过实战检验的解决方案。

在这里插入图片描述
posted on 2026-04-05 19:40  mthoutai  阅读(93)  评论(0)    收藏  举报