• システム開発に関わる内容をざっくりと書いていく

ChatGPTにワードファイルを読み込ませる【C#】

ChatGPTにワードファイルをプロンプトに送り、感想などの返答をもらう:簡単なAPIでの実装コード

[HttpGet]
public async Task<string?> GetFromWord(string path)
{
    using (WordprocessingDocument doc = WordprocessingDocument.Open(path, false))
    {
        string text = "";
        foreach (var para in doc.MainDocumentPart.Document.Descendants<Paragraph>())
        {
            text += para.InnerText + "\n";
        }
        System.Console.WriteLine(text);

        return await GetChatGptResponse("以下のドキュメントについての感想をください" + text);
    }
}

private async Task<string?> GetChatGptResponse(string prompt)
{
    var openAiService = new OpenAIService(new OpenAiOptions()
    {
        ApiKey = "yourApiKey"
    });
    Console.WriteLine(prompt);
    var result = await openAiService.Completions.CreateCompletion(new CompletionCreateRequest()
    {
        Prompt = prompt,
        Echo = false,
        MaxTokens = 300 // about
    }, Models.TextDavinciV3);
    if (result.Successful)
    {
        return result.Choices.Select(x => x.Text).FirstOrDefault();
    }
    else
        return null;
}

実践的には下記のようなものも必要

1. APIキーのセキュリティ対策

この実装ではAPIキーをコード内に直接記述していますが、実際のプロジェクトでは、APIキーは外部の設定ファイルや環境変数を使用して安全に管理することが推奨されます。ハードコーディングされたAPIキーは、セキュリティリスクを高める可能性があるため注意が必要です。

推奨方法:

  • APIキーを環境変数や秘密管理ツール(例: Azure Key Vault, AWS Secrets Manager)に格納する。
  • ローカル開発環境と本番環境で異なるAPIキーを使えるように設定を分ける。

2. 非同期処理のパフォーマンス

GetFromWordGetChatGptResponseは非同期タスクとして実装されています。非同期処理は、API呼び出しのパフォーマンス向上に重要ですが、特に複数のファイルを並列で処理する場合に活用すると、パフォーマンスがさらに向上します。ファイル数が増加してもアプリケーションがスムーズに動作するよう、非同期処理を積極的に活用することを推奨します。

改善案:

  • 複数のWordファイルを同時に処理する場合、Task.WhenAll()などを使用して並列処理を行う。

3. ログの充実化

現在の実装ではConsole.WriteLineを使用してログ出力を行っていますが、実際の運用環境では、より詳細なロギングが必要です。例えば、API呼び出しの成功・失敗、処理時間、ユーザーアクションなどをロギングすることで、後からトラブルシューティングがしやすくなります。

推奨方法:

  • SerilogNLogなどのログフレームワークを導入し、適切なログレベル(例: Info, Error, Warning)でログを記録。
  • API呼び出しごとに処理時間を計測し、性能のモニタリングに役立てる。

4. エラーハンドリングの強化

予期しないエラーやAPIの失敗を適切に処理し、ユーザーにフィードバックを提供することは、ユーザー体験の向上に繋がります。現在はAPI呼び出しが失敗した場合にnullを返すだけですが、詳細なエラー情報を返すと、問題の特定が容易になります。

改善案:

  • APIエラーやネットワークエラーの場合に具体的なエラーメッセージをログに記録し、ユーザーに表示する。
  • カスタムエラーメッセージを使用して、ユーザーに次のステップを案内(例: 「再試行してください」)。

5. ファイルアップロード機能の実装

記事内のコードは、指定されたパスからWordファイルを読み込む方式を取っていますが、Webアプリケーションとしては、ユーザーがブラウザからWordファイルをアップロードできるようにする方が実用的です。IFormFileを使って、ファイルアップロード機能を実装することで、より使いやすいアプリケーションにすることができます。

実装案:

  • IFormFileを使ってユーザーがファイルをアップロードし、そのファイルの内容を読み取る。
  • アップロードされたファイルを一時ディレクトリに保存し、そこから読み込む。
[HttpPost]
public async Task<IActionResult> UploadFile(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("ファイルがアップロードされていません");

// アップロードされたファイルを保存するか、一時ディレクトリに置く
var filePath = Path.GetTempFileName();
using (var stream = System.IO.File.Create(filePath))
{
await file.CopyToAsync(stream);
}

// ファイルの処理を行い、結果を返す
var response = await GetFromWord(filePath);
return Ok(response);
}

6. ChatGPTのモデル設定やチューニング

現在の実装では、TextDavinciV3モデルを使用していますが、他のモデル(例: GPT-4)も検討すると、応答の品質やトークン数の調整に柔軟性が増します。プロジェクトの要件に応じて、最適なモデルを選びましょう。

推奨方法:

  • より短い応答が必要な場合は、curiebabbageなどの軽量モデルを選択する。
  • 長い文書や複雑な質問を扱う場合は、より高度なモデルを使用して応答の精度を向上させる。