Flutter AI功能插件aub_ai的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter AI功能插件aub_ai的使用

简介

AubAI 是一个专为 Flutter/Dart 开发者设计的包,旨在为应用提供设备端生成式人工智能(Gen-AI)能力。无论是生成文本、增强用户交互还是其他AI驱动的任务,AubAI都能满足您的需求。

主要特点和功能

  • 先进的Gen-AI集成:利用尖端的语言模型进行平滑的文本生成。
  • 跨平台兼容性:支持多个操作系统,包括 macOS、Windows、Linux、Android 和 iOS。
  • 用户友好设计:简化集成,使复杂的AI功能对所有开发者都易于使用。
  • 开源社区:欢迎贡献者参与开发,推动创新。

设置步骤

  1. pubspec.yaml 文件中添加以下依赖:

    dependencies:
      aub_ai: ^1.0.0
    
  2. 运行 flutter pub get 安装包。

  3. 在 Dart 代码中导入包:

    import 'package:aub_ai/aub_ai.dart';
    
  4. 使用 AubAI 与AI进行对话:

    /// AI输出将存储在这个变量中,可以用于Text()小部件等。
    String outputByAI = '';
    
    /// 示例:如何使用AubAI与AI对话。
    Future<void> example() async {
      // 确保模型文件是GGUF格式。
      const String filePath = 'path/to/model.gguf';
    
      // 用户开始对话的提示。
      const String promptByUser = '为什么天空是蓝色的?';
    
      // 预定义的提示模板可用。
      final promptTemplate = PromptTemplate.chatML().copyWith(
        prompt: promptByUser,
      );
    
      // 执行主要操作的函数。
      await talkAsync(
          filePathToModel: filePath,
          promptTemplate: promptTemplate,
          onTokenGenerated: (String token) {
            // 每当AI生成一个令牌时调用此回调。
            setState(() {
              outputByAI += token;
            });
          },
        );
    }
    

完整示例Demo

以下是完整的Flutter应用程序示例,展示了如何使用AubAI与AI进行对话:

import 'dart:io';
import 'package:aub_ai/aub_ai.dart';
import 'package:aub_ai/prompt_template.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

enum TalkAsyncState {
  idle,
  thinking,
  talking,
}

class _MyAppState extends State<MyApp> {
  final TextEditingController textControllerUserPrompt =
      TextEditingController();

  String responseFromAi = '';
  TalkAsyncState talkAsyncState = TalkAsyncState.idle;

  File? file;

  PromptTemplate promptTemplate = PromptTemplate.chatML().copyWith(
    contextSize: 2048,
  );

  late final String _promptTemplateDefaultPrompt;

  @override
  void initState() {
    super.initState();
    _promptTemplateDefaultPrompt = promptTemplate.prompt;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.red,
        useMaterial3: true,
      ),
      home: Scaffold(
        appBar: AppBar(
          actions: [
            IconButton(
              onPressed: talkAsyncState == TalkAsyncState.idle && file != null
                  ? () {
                      setState(
                        () {
                          file = null;
                          textControllerUserPrompt.clear();
                          responseFromAi = '';
                          promptTemplate = promptTemplate.copyWith(
                            prompt: '',
                          );
                          talkAsyncState = TalkAsyncState.idle;
                        },
                      );
                    }
                  : null,
              icon: const Icon(Icons.clear),
              tooltip: 'Reset',
            ),
          ],
        ),
        body: SafeArea(
          child: Center(
            child: Container(
              constraints: const BoxConstraints(
                maxWidth: 960,
              ),
              child: SingleChildScrollView(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    const CircleAvatar(
                      minRadius: 64,
                      maxRadius: 128,
                      backgroundImage: AssetImage(
                        'assets/appicon_avatar.png',
                      ),
                    ),
                    const SizedBox(height: 16),
                    const Text(
                      'Daniel Breedeveld',
                      style: TextStyle(
                        fontSize: 12,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 16),
                    const Text(
                      'Ask me anything!',
                      style: TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 16),
                    if (file == null)
                      Column(
                        children: [
                          const Padding(
                            padding: EdgeInsets.all(8.0),
                            child: Text(
                              'In order to start, please select a model file from your device',
                              textAlign: TextAlign.center,
                              style: TextStyle(
                                fontSize: 16,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                          const Text(
                            'This file is what contains the knowledge of the AI',
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              fontSize: 12,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: ElevatedButton(
                              onPressed: () async {
                                FilePickerResult? result =
                                    await FilePicker.platform.pickFiles();

                                if (result == null) {
                                  return;
                                }

                                final tmpFile = File(result.files.single.path!);
                                setState(() {
                                  file = tmpFile;
                                });
                              },
                              child: const Text('Pick a file'),
                            ),
                          ),
                        ],
                      ),
                    Column(
                      children: [
                        Padding(
                          padding: const EdgeInsets.symmetric(
                            horizontal: 16,
                            vertical: 8,
                          ),
                          child: Row(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Expanded(
                                child: TextField(
                                  controller: textControllerUserPrompt,
                                  textCapitalization:
                                      TextCapitalization.sentences,
                                  onSubmitted: (_) => _sendPromptToAi(),
                                  enabled: file != null &&
                                      talkAsyncState == TalkAsyncState.idle,
                                  decoration: InputDecoration(
                                    border: const OutlineInputBorder(),
                                    labelText:
                                        'Example: "$_promptTemplateDefaultPrompt"',
                                  ),
                                ),
                              ),
                              Flexible(
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Stack(
                                    children: [
                                      Tooltip(
                                        waitDuration:
                                            const Duration(seconds: 1),
                                        message: talkAsyncState ==
                                                    TalkAsyncState.thinking ||
                                                talkAsyncState ==
                                                    TalkAsyncState.talking
                                            ? 'The AI is busy, please wait...'
                                            : 'Send this prompt to the AI in order to get a response',
                                        child: ElevatedButton.icon(
                                          style: ElevatedButton.styleFrom(
                                            shape: const RoundedRectangleBorder(
                                              borderRadius: BorderRadius.all(
                                                Radius.circular(8),
                                              ),
                                            ),
                                            minimumSize: const Size(0, 64),
                                          ),
                                          onPressed: file != null &&
                                                  talkAsyncState ==
                                                      TalkAsyncState.idle
                                              ? () => _sendPromptToAi()
                                              : null,
                                          icon: const Icon(Icons.send),
                                          label: const Text('Send'),
                                        ),
                                      ),
                                      if (talkAsyncState ==
                                              TalkAsyncState.thinking ||
                                          talkAsyncState ==
                                              TalkAsyncState.talking)
                                        const Positioned.fill(
                                          child: Align(
                                            alignment: Alignment.bottomCenter,
                                            child: Padding(
                                              padding: EdgeInsets.symmetric(
                                                horizontal: 4,
                                              ),
                                              child: LinearProgressIndicator(
                                                borderRadius: BorderRadius.all(
                                                  Radius.circular(16),
                                                ),
                                              ),
                                            ),
                                          ),
                                        ),
                                    ],
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                    Center(
                      child: Container(
                        padding: const EdgeInsets.all(8),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Center(
                                child: Column(
                              children: [
                                if (talkAsyncState == TalkAsyncState.talking ||
                                    responseFromAi.isNotEmpty) ...[
                                  Padding(
                                    padding: const EdgeInsets.all(8.0),
                                    child: TextField(
                                      controller: TextEditingController(
                                        text: responseFromAi,
                                      ),
                                      maxLines: 20,
                                      readOnly: true,
                                      decoration: const InputDecoration(
                                        border: OutlineInputBorder(),
                                      ),
                                    ),
                                  ),
                                ],
                                if (talkAsyncState == TalkAsyncState.thinking &&
                                    responseFromAi.isEmpty)
                                  Center(
                                    child: Column(
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      mainAxisSize: MainAxisSize.max,
                                      children: [
                                        Text(
                                          '"${promptTemplate.prompt}"',
                                          textAlign: TextAlign.center,
                                          style: const TextStyle(
                                            fontSize: 16,
                                            fontWeight: FontWeight.bold,
                                          ),
                                        ),
                                        const SizedBox(height: 32),
                                        const Text(
                                          "Thinking...",
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                            fontSize: 12,
                                            fontWeight: FontWeight.bold,
                                          ),
                                        ),
                                        const SizedBox(height: 32),
                                        const CircularProgressIndicator
                                            .adaptive(),
                                      ],
                                    ),
                                  ),
                              ],
                            )),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }

  void _sendPromptToAi() async {
    if (file == null || textControllerUserPrompt.text.isEmpty) {
      return;
    }

    promptTemplate = PromptTemplate.chatML().copyWith(
      prompt: textControllerUserPrompt.text.trim(),
    );

    setState(() {
      talkAsyncState = TalkAsyncState.thinking;
      textControllerUserPrompt.clear();
    });

    debugPrint('Prompt: ${promptTemplate.prompt}');

    await talkAsync(
      filePathToModel: file!.path,
      promptTemplate: promptTemplate,
      onTokenGenerated: (String token) {
        if (talkAsyncState == TalkAsyncState.thinking) {
          setState(() {
            talkAsyncState = TalkAsyncState.talking;
            responseFromAi = '';
          });
        }

        setState(() {
          responseFromAi += token;
        });
      },
    );

    setState(() {
      talkAsyncState = TalkAsyncState.idle;
    });
  }
}

以上示例展示了一个完整的Flutter应用程序,演示了如何使用AubAI与AI进行对话,并处理响应。希望这个示例能帮助您快速上手并充分利用AubAI的强大功能!


更多关于Flutter AI功能插件aub_ai的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter AI功能插件aub_ai的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中集成和使用aub_ai插件的示例代码案例。aub_ai是一个提供AI功能的Flutter插件,虽然具体的AI功能可能因插件版本和配置而异,但以下示例将展示如何基本集成和使用该插件。

首先,确保你已经在pubspec.yaml文件中添加了aub_ai依赖:

dependencies:
  flutter:
    sdk: flutter
  aub_ai: ^最新版本号  # 请替换为实际最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用aub_ai插件。以下是一个简单的示例,展示如何初始化插件并进行一次AI调用(假设aub_ai提供了某种文本分析功能):

import 'package:flutter/material.dart';
import 'package:aub_ai/aub_ai.dart'; // 导入aub_ai插件

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Aub AI Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AubAIDemo(),
    );
  }
}

class AubAIDemo extends StatefulWidget {
  @override
  _AubAIDemoState createState() => _AubAIDemoState();
}

class _AubAIDemoState extends State<AubAIDemo> {
  String result = "";

  @override
  void initState() {
    super.initState();
    // 初始化AubAI客户端(假设需要API密钥或配置)
    AubAI.instance.init(apiKey: "你的API密钥"); // 如果需要API密钥的话

    // 调用AI功能(例如文本分析)
    callAubAIFunction();
  }

  Future<void> callAubAIFunction() async {
    try {
      // 假设AubAI有一个名为analyzeText的方法
      var response = await AubAI.instance.analyzeText(text: "Hello, Aub AI!");
      
      // 更新UI
      setState(() {
        result = response.result; // 假设response有一个result字段
      });
    } catch (e) {
      print("Error calling Aub AI: $e");
      setState(() {
        result = "Error: $e";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Aub AI Demo'),
      ),
      body: Center(
        child: Text(
          result,
          style: TextStyle(fontSize: 20),
        ),
      ),
    );
  }
}

注意

  1. 上述代码中的AubAI.instance.initAubAI.instance.analyzeText方法是假设的,实际使用时需要根据aub_ai插件的文档来调整。
  2. 如果aub_ai插件需要初始化配置(如API密钥),请确保在调用任何AI功能之前完成初始化。
  3. 错误处理部分(catch块)用于捕获和处理在调用AI功能时可能发生的任何异常。

由于aub_ai插件的具体API和功能可能会随着版本更新而变化,因此强烈建议查阅该插件的官方文档以获取最新和最准确的信息。如果插件提供了示例代码或教程,那也将是一个很好的学习资源。

回到顶部