ChatGPT APIとC#(またはPython)を活用したAIメール応答システムの構築方法
目次
はじめに
先日上司から、「受信メールの内容に基づいて最適な返信文を自動で提案できるシステムは構築できるか?」と尋ねられました。その時点ではそのようなシステムを作ったことがなかったため、自分で調べて実際に実装してみました。本記事では、その過程を共有し、ChatGPT APIとC#またはPythonを使用して、登録済みのテンプレートから最適な返信文を自動的に提案するシステムを構築する方法について解説します。ぜひ参考にしてください。
ChatGPT APIのAPI keysを取得する
API keysは今回の開発において必須ですので、必ず取得してください。以下の手順に従ってください。
1.OpenAIの公式サイトにアクセス
2.Productボタンをクリック
3.API Loginをクリック
4.APIをクリック
5.Dashboardをクリック
6.API Keysをクリック
7.Create new Secret Keyをクリックして、任意のNameを付けてCreate Secret Keyをクリックします。
8.Copyボタンを押して、API Keyをコピーします。※重要
9.なお、料金の支払いについては料金の支払いは「Your Profile」の「Billing」セクションにあります。
一定金額を下回った場合、自動的に課金されるパターンとそうでないパターンがあります。さらに無料トライアルがあり、最初の5ドル分が無料という情報もありますが、無料トライアルがないという情報もあります。最新の情報を確認してください
この手順に従って、APIキーを取得し、開発を進めてください。
コーディング
C#でコーディング
次に、取得したAPIキーを活用して、Visual StudioでWindowsフォームアプリケーションを作成しました。使用言語はC#で、各コンポーネントの名称も記載しています。
動作方法はシンプルです。受信したメールの内容をリッチテキストボックス(richTxt入力
)に入力し、出力ボタンを押下すると、適切な返信候補がリッチテキストボックス(richTxt候補01
)に表示されます。
以下は、C#コードの全体です。
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Windows.Forms;
namespace ChatGPT_TestApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn出力_Click(object sender, EventArgs e)
{
// ユーザーがリッチテキストボックスに入力したデータを取得
string data = richTxt入力.Text;
// 入力が空白またはnullの場合、ユーザーにメッセージを表示して処理を中断
if (string.IsNullOrWhiteSpace(data))
{
MessageBox.Show("文面を入力してください");
return;
}
// 処理時間を計測するためにStopwatchクラスを生成
var sw = new System.Diagnostics.Stopwatch();
// 計測開始
sw.Start();
// APIキーの設定
string apiKey = "上記で取得したAPIキーを入れてください";
// APIのURL(OpenAIのチャットモデルを使用)
string apiUrl = "https://api.openai.com/v1/chat/completions";
// 事前に定義されたプロンプトのテンプレート
string strPrePrompt = @"#命令書:
あなたはメールの自動応答システムです。
以下の制約条件と入力文をもとに、最高の結果を出力してください。
#制約条件:
・#入力文 に相手から送られてたメールがあります。#テンプレート の中にある返信メールのテンプレートの一覧からふさわしい文面を上位3つ出力して
・テンプレートの文面は、それぞれ☆☆☆☆☆☆☆☆☆☆で区切っています。
・テンプレートを出力するときは、文面を省略せずに一字一句正確に出力して
・もっともふさわしいと思うものから順番に上から出力して
・出力するときは、わかりやすく見やすいフォーマットで出力して
・もし該当するテンプレートがない場合は、「該当なし」と出して
・もし該当するテンプレートがない場合は、絶対に文面を作成をしないで
・出力する必ずすべてテキストベースで、コードスニペットや強調表示のように文字を大きくするや強調はしないで
候補1
----------
候補2
----------
候補3
----------
のフォーマットで出力して
#入力文:
{0}
#テンプレート:
件名:お問い合わせありがとうございます
本文:お問い合わせいただき、ありがとうございます。現在、内容を確認しておりますので、しばらくお待ちください。
☆☆☆☆☆☆☆☆☆☆
件名:ご注文確認のお知らせ
本文:ご注文ありがとうございます。確認の上、発送手続きを進めております。発送の際は改めてご連絡いたします。
☆☆☆☆☆☆☆☆☆☆
件名:ご予約ありがとうございます
本文:ご予約を承りました。ご来店をお待ちしております。ご不明な点がございましたらお気軽にご連絡ください。
☆☆☆☆☆☆☆☆☆☆
件名:お見積もりのご案内
本文:お見積もりの件につきまして、添付ファイルをご確認ください。不明点や変更のご希望がございましたらお知らせください。
☆☆☆☆☆☆☆☆☆☆
件名:面接のお知らせ
本文:面接の日程が決定いたしました。以下の日程でお越しください。日時:〇〇月〇〇日 〇〇時 場所:弊社オフィス
☆☆☆☆☆☆☆☆☆☆
件名:納期のご連絡
本文:納期が近づいておりますのでご連絡いたします。予定通り〇〇日に納品いたしますのでご確認ください。
☆☆☆☆☆☆☆☆☆☆
件名:お祝いのメッセージ
本文:〇〇様、このたびは誠におめでとうございます。今後のご活躍をお祈り申し上げます。
☆☆☆☆☆☆☆☆☆☆
....
";
// 入力されたデータをプロンプトテンプレートに埋め込む
string prompt = string.Format(strPrePrompt, data);
// APIに送信するリクエストボディを作成
var requestBody = new
{
model = "gpt-4o-mini", // 使用するGPTモデルを指定
messages = new[]
{
new { role = "system", content = "You are a helpful assistant." }, // システムメッセージ
new { role = "user", content = prompt } // ユーザーメッセージとしてプロンプトを送信
},
temperature = 0 // 応答の一貫性を保つために、ランダム性を排除
};
// HttpClientを使用してAPIリクエストを送信
using (var client = new HttpClient())
{
// APIキーをHTTPヘッダーに設定
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
// リクエストボディをJSON形式にシリアライズして送信
var jsonContent = new StringContent(JsonSerializer.Serialize(requestBody), Encoding.UTF8, "application/json");
// POSTリクエストをAPIに送信し、結果を受信
var response = client.PostAsync(apiUrl, jsonContent).Result;
// 応答が成功したかをチェック
if (response.IsSuccessStatusCode)
{
// 成功した場合、応答内容を取得して表示
var responseContent = response.Content.ReadAsStringAsync().Result;
var jsonDocument = JsonDocument.Parse(responseContent);
var text = jsonDocument.RootElement
.GetProperty("choices")[0]
.GetProperty("message")
.GetProperty("content")
.GetString();
// 取得したテキストをリッチテキストボックスに表示
richTxt候補01.Text = text;
}
else
{
// 応答が失敗した場合、エラーメッセージを表示
var errorContent = response.Content.ReadAsStringAsync().Result;
MessageBox.Show($"Error: {response.StatusCode}");
MessageBox.Show(errorContent);
}
}
// 処理時間の計測を終了
sw.Stop();
// 経過時間を表示
TimeSpan ts = sw.Elapsed;
MessageBox.Show($"処理時間: {ts.Hours}時間 {ts.Minutes}分 {ts.Seconds}秒 {ts.Milliseconds}ミリ秒");
}
}
}
今回、「受信メールの内容に基づいて最適な返信文を自動で提案できるシステム」の構築方法はプロンプト内に必要な情報やテンプレートをあらかじめ含めておくことで、ChatGPTがそれに基づいて適切な返信を生成します。
なお、プロンプトの書き方は「深津式プロンプト」を参考にしました。また、使用しているGPTモデルはgpt-4o-mini
ですが、モデルのバージョンによっては利用できなくなる可能性がありますので、最新の利用可能なモデルについてはOpenAIの公式サイトをご確認ください。
Pythonでコーディング
C#で構築した同じ機能をPythonで実装する方法も紹介します。なお動作環境はコマンドプロンプトです。GUIはありません。
import requests
import time
import json
import sys
def main():
if len(sys.argv) < 2:
print("文面を入力してください")
return
# コマンドライン引数から文面を取得
data = " ".join(sys.argv[1:])
start_time = time.time()
api_key = "上記で取得したAPIキーを入れてください"; # APIキーを設定
api_url = "https://api.openai.com/v1/chat/completions"
str_pre_prompt = """#命令書:
あなたはメールの自動応答システムです。
以下の制約条件と入力文をもとに、最高の結果を出力してください。
#制約条件:
・#入力文 に相手から送られてたメールがあります。#テンプレート の中にある返信メールのテンプレートの一覧からふさわしい文面を上位3つ出力して
・テンプレートの文面は、それぞれ☆☆☆☆☆☆☆☆☆☆で区切っています。
・テンプレートを出力するときは、文面を省略せずに一字一句正確に出力して
・もっともふさわしいと思うものから順番に上から出力して
・出力するときは、わかりやすく見やすいフォーマットで出力して
・もし該当するテンプレートがない場合は、「該当なし」と出して
・もし該当するテンプレートがない場合は、絶対に文面を作成をしないで
・出力する必ずすべてテキストベースで、コードスニペットや強調表示のように文字を大きくするや強調はしないで
候補1
----------
候補2
----------
候補3
----------
のフォーマットで出力して
#入力文:
{0}
#テンプレート:
件名:お問い合わせありがとうございます
本文:お問い合わせいただき、ありがとうございます。現在、内容を確認しておりますので、しばらくお待ちください。
☆☆☆☆☆☆☆☆☆☆
件名:ご注文確認のお知らせ
本文:ご注文ありがとうございます。確認の上、発送手続きを進めております。発送の際は改めてご連絡いたします。
☆☆☆☆☆☆☆☆☆☆
件名:ご予約ありがとうございます
本文:ご予約を承りました。ご来店をお待ちしております。ご不明な点がございましたらお気軽にご連絡ください。
☆☆☆☆☆☆☆☆☆☆
件名:お見積もりのご案内
本文:お見積もりの件につきまして、添付ファイルをご確認ください。不明点や変更のご希望がございましたらお知らせください。
☆☆☆☆☆☆☆☆☆☆
件名:面接のお知らせ
本文:面接の日程が決定いたしました。以下の日程でお越しください。日時:〇〇月〇〇日 〇〇時 場所:弊社オフィス
☆☆☆☆☆☆☆☆☆☆
件名:納期のご連絡
本文:納期が近づいておりますのでご連絡いたします。予定通り〇〇日に納品いたしますのでご確認ください。
☆☆☆☆☆☆☆☆☆☆
件名:お祝いのメッセージ
本文:〇〇様、このたびは誠におめでとうございます。今後のご活躍をお祈り申し上げます。
☆☆☆☆☆☆☆☆☆☆
....
"""
prompt = str_pre_prompt.format(data)
request_body = {
"model": "gpt-4o-mini",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
],
"temperature": 0
}
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
response = requests.post(api_url, headers=headers, data=json.dumps(request_body))
if response.status_code == 200:
response_content = response.json()
text = response_content['choices'][0]['message']['content']
print(text)
else:
error_content = response.text
print(f"Error: {response.status_code}")
print(error_content)
elapsed_time = time.time() - start_time
print(f"処理時間: {int(elapsed_time // 3600)}時間 {int((elapsed_time % 3600) // 60)}分 {int(elapsed_time % 60)}秒 {int((elapsed_time % 1) * 1000)}ミリ秒")
if __name__ == "__main__":
main()
なおこのコードを実行するときはこのように引数に、受信メールの内容を設定して実行してください。
python generate_email_responses.py お世話になっております。先日ご注文させていただきました商品が、まだ手元に届いておりません。発送状況をご確認いただき、状況を教えていただけますでしょうか。ご対応のほど、よろしくお願い申し上げます。
APIの使用料金
なお、ChatGPT APIを使用するには料金がかかりります。2024年8月29日現在の料金ですが、下記の通りです。
GPT-4oの料金表
モデル | 通常料金 (入力) | バッチAPI料金 (入力) | 通常料金 (出力) | バッチAPI料金 (出力) |
---|---|---|---|---|
gpt-4o | $5.00 / 1M | $2.50 / 1M | $15.00 / 1M | $7.50 / 1M |
gpt-4o-2024-08-06 | $2.50 / 1M | $1.25 / 1M | $10.00 / 1M | $5.00 / 1M |
gpt-4o-2024-05-13 | $5.00 / 1M | $2.50 / 1M | $15.00 / 1M | $7.50 / 1M |
GPT-4o Miniの料金表
モデル | 通常料金 (入力) | バッチAPI料金 (入力) | 通常料金 (出力) | バッチAPI料金 (出力) |
---|---|---|---|---|
gpt-4o-mini | $0.150 / 1M | $0.075 / 1M | $0.600 / 1M | $0.300 / 1M |
gpt-4o-mini-2024-07-18 | $0.150 / 1M | $0.075 / 1M | $0.600 / 1M | $0.300 / 1M |
最新の利用可能なモデルと料金については、OpenAIの公式サイトをご確認ください。また、文字数からトークン数を計算するには、OpenAI公式のTokenizerをご利用ください。
さいごに
今回のシステム構築を通じて、AI技術の進歩が日常業務にどれだけ役立つかを実感しました。特に、受信メールに応じた最適な返信を自動で提案する機能は、業務効率を大幅に向上させる可能性があります。また、C#やPythonといった一般的なプログラミング言語とChatGPT APIを組み合わせることで、比較的簡単に高機能なシステムを開発できることにも驚きました。
今後は、さらに多様なテンプレートや条件を追加し、より高度な応答システムを作成していきたいと考えています。また、他のAPIやツールとの連携も検討し、業務効率化のさらなる可能性を探っていく予定です。この記事が皆さんの開発の参考になれば幸いです。
参考文献
このカテゴリの最新記事
2024.08.07
2023.10.02
2023.11.28
2023.04.24