FlutterでClaudeを呼び出してみた

# FlutterでClaudeを呼び出したい！
FlutterでClaudeを呼び出したい時ありますよね、
パッケージを使う方と使わない方を紹介します
Akira_0809です、

# パッケージの方
以下のパッケージを使います

https://pub.dev/packages/anthropic_dart

## インストール
pubspec.yamlに追加
```dart:pubspec.yaml
dependencies:
  anthropic_dart: ^1.0.1
```
Getする！
```console
$ flutter pub get
```

## 使い方
### 簡単に試す
```dart
final List<Response> response = await service.sendHello();
```
### テキスト入力
```dart
import 'package:anthropic_dart/anthropic_dart.dart';

Future<String> talk(String text) async {
    const String model = "claude-3-haiku-20240307";
    final service = AnthropicService(dotenv.get("ANTHROPIC_API_KEY"), model: model);
    var request = Request();
    request.model = model;
    request.maxTokens = 1024;
    request.messages = [
      Message(
        role: "user",
        content: text,
      )
    ];
    var response = await service.sendRequest(request: request);

    // debugPrint('Response body: ${response.toJson()["content"][0]["text"]}');

    return response.toJson()["content"][0]["text"];
}
```
### 出力
```text
{
    id: msg_01RYfE4NMXifqPDnKdDfPfHd, 
    type: message, 
    role: assistant, 
    model: claude-3-haiku-20240307, 
    content: [{type: text, text: output_text}], 
    stop_reason: end_turn, 
    stop_sequence: null, 
    usage: {input_tokens: 38, output_tokens: 66}
}
```
### 画像入力

:::note warn
画像の大きさは5MB以下
:::
  
```dart
var currentDirectory = Directory.current;

var file = File('${currentDirectory.path}/example/beHappy.png');

MessageWithImages msg = MessageWithImages(role: 'user', content: [
  ContentWithImage(
      type: 'image',
      source: Source(
          type: 'base64',
          mediaType: 'image/png',
          data: file.readAsBytesSync())),
  Content(type: 'text', text: 'Describe what is in the image'),
]);

var requestWithImage = RequestWithImages(
    model: "claude-3-haiku-20240307", maxTokens: 2400, messages: [msg]);
var responseImages =
    await service.sendRequestWithImages(request: requestWithImage);
print('\n\nEXAMPLE: requestWithImage response $mm ${responseImages.toJson()} $mm');
```
画像入力は試していないので動作するかわかりません。

# 頑張る方
```dart
Future<String> claude(String prompt, String systemPrompt) async {
    const String model = "claude-3-haiku-20240307";
    final String apiKey = dotenv.get("ANTHROPIC_API_KEY");
    final url = Uri.https('api.anthropic.com', '/v1/messages');

    final headers = {
      'Content-Type': 'application/json',
      'X-API-Key': apiKey,
      'Anthropic-Version': '2023-06-01',
    };

    final body = jsonEncode({
      'model': model,
      'max_tokens': 1024,
      'system': systemPrompt,
      'messages': [
        {'role': 'user', 'content': prompt},
      ]
    });

    final response = await http.post(
      url,
      headers: headers,
      body: body,
    );

    if (response.statusCode == 200) {
      try {
        final Map<String, dynamic> responseData = jsonDecode(utf8.decode(response.bodyBytes));
        return responseData['content'][0]['text'];
      } catch (e) {
        debugPrint('Error decoding response: $e');
        return "";
      }
    } else {
      const String responseData = "error";
      debugPrint('Error response: $response');
      return responseData;
    }
  }
```

パッケージの方では対応していなかったSystemPromptが使えます！
デコードしないと文字化けするので注意！

# 終わり
多分動くはず
変だったらコメントお願いします