小説の場面をGPTに書かせる試み 4/100

前回の失敗:GPTから返ってくるcontentが、必ずしもJSON形式であるとは限らない

systemメッセージやassistantメッセージのcontentを介して、返り値の形式がJSONであること明示したり例示したりしても、JSONに変換できる文字列ではないものが返ってくることがしばしばある。
それを、今回は、try/exceptを使って、握りつぶす。
(try/exceptは実際に起っている問題を隠蔽するので、あまり使わないほうがよい。しかし、このコードで問題が起こっても困るのは俺だけなので、使う。)

実際のコード

GPT_KEY = "YOUR_API_KEY"

!pip install openai
import openai
import json
import time
def is_valid_json(input_string):
    if input_string == None or input_string == "":
      return False

    try:
        json.loads(input_string)
        return True
    except:
        return False

def gpt3(system_content, user_content, assistant_content):
    openai.api_key = GPT_KEY
    response = openai.ChatCompletion.create(
        model = "gpt-3.5-turbo",
        messages = [
            {"role": "system",
             "content": system_content},
            {"role": "assistant",
             "content": assistant_content},
            {"role": "user",
             "content": user_content},
        ],
        n = 1
    )

    return response

def gpt3_list(system_content, user_content_list, assistant_content_list, n = 1):
    openai.api_key = GPT_KEY

    messages = [{"role": "system", "content": system_content},]

    list_length = max(len(assistant_content_list), len(user_content_list))

    for i in range(0, list_length):

      if i < len(user_content_list):
        messages.append({"role": "user", "content": user_content_list[i]})

      if i < len(assistant_content_list):
        messages.append({"role": "assistant", "content": assistant_content_list[i]})

    response = openai.ChatCompletion.create(
        model = "gpt-3.5-turbo",
        messages = messages,
        n = n
    )

    return response
system_content = """
入力された情報をもとに、物語の登場人物の反応となる行動をJSONで返してください。
入力されたJSONファイルは、行動の主体、対象、その行動、その行動をした際の発言を表します。
あなたは、行動の対象からの反応をJSONで返します。そのJSONも、反応を示す人物が起こした行為の行動の主体、対象、その行動、その行動をした際の発言を表します。
"""

melos_content_1= """
{"主体":"メロス","対象":"セリヌンティウス", "行動":"殴る", "発言":"「俺の味噌汁を返せ!」"}
"""

selinun_content_1 = """
{"主体":"セリヌンティウス","対象":"メロス", "行動":"殴り返す", "発言":"「お前だって俺のたくあん漬けを取っただろ!」"}
"""

melos_content_2 = """
{"主体":"メロス","対象":"セリヌンティウス", "行動":"憤慨する", "発言":"「お前に貸した10円をまだ返してもらってない!」"}
"""

melos_content_list = [melos_content_1, melos_content_2]
selinun_content_list = [selinun_content_1]
history = []
count = 0

for i in range(5):
  is_json = False
  count = 0

  while not is_json and count < 100:
    count += 1
    try:
      response_from_selinun_to_melos = gpt3_list(system_content, melos_content_list, selinun_content_list, n = 1)
    except:
      response_from_selinun_to_melos = None
      print(f"wait for 5 sec in {i}th iteretion")
      time.sleep(5)

    is_json = is_valid_json(response_from_selinun_to_melos.choices[0]["message"]["content"])
  
  json_object = json.loads(response_from_selinun_to_melos.choices[0]["message"]["content"])
  if list(json_object.keys())[0] == "主体" and json_object["主体"] == "メロス":
    melos_content_list.append(response_from_selinun_to_melos.choices[0]["message"]["content"])
  if list(json_object.keys())[0] == "主体" and json_object["主体"] == "セリヌンティウス":
    selinun_content_list.append(response_from_selinun_to_melos.choices[0]["message"]["content"])

  history.append(response_from_selinun_to_melos.choices[0]["message"]["content"])

  is_json = False
  count = 0

  while not is_json and count < 100:
    count += 1
    try:
      response_from_melos_to_selinun = gpt3_list(system_content, selinun_content_list, melos_content_list, n = 1)
    except:
      response_from_melos_to_selinun = None
      print(f"wait for 5 sec in {i}th iteretion")
      time.sleep(5)

    is_json = is_valid_json(response_from_melos_to_selinun.choices[0]["message"]["content"])

  json_object = json.loads(response_from_melos_to_selinun.choices[0]["message"]["content"])
  if list(json_object.keys())[0] == "主体" and json_object["主体"] == "メロス":
    melos_content_list.append(response_from_melos_to_selinun.choices[0]["message"]["content"])
  if list(json_object.keys())[0] == "主体" and json_object["主体"] == "セリヌンティウス":
    selinun_content_list.append(response_from_melos_to_selinun.choices[0]["message"]["content"])

  history.append(response_from_melos_to_selinun.choices[0]["message"]["content"])

for item in history:
  print(item)
  

結果その1

{"主体":"セリヌンティウス", "対象":"周りの人々", "行動":"不快そうに顔をしかめる", "発言":"「最近は金銭問題ばかりで、困るよなぁ…」"}
{"主体":"周りの人々","対象":"セリヌンティウス", "行動":"無言で視線を向ける", "発言":null}
{"主体":"セリヌンティウス", "対象":"メロス", "行動":"怒りをぶつける", "発言":"「お前、10円って小銭でも気になるのかよ!?返したかったらもっと早く言えよ!!」"}
{"主体":"周りの人々","対象":"セリヌンティウス", "行動":"心配そうに見つめる", "発言":"「あの人、最近イライラしてるみたいだね…大丈夫かな?」"}
{"主体":"周りの人々", "対象":"セリヌンティウス", "行動":"「あの人怒りっぽいから気をつけたほうがいいよ」と密かに話し合う", "発言":""}
{"主体":"周りの人々","対象":"セリヌンティウス", "行動":"苦笑いする", "発言":"「また始まったよこの二人…」"}
{"主体":"周りの人々", "対象":"メロス", "行動":"追い払う", "発言":"「お前たちとは関わりたくないから、早く立ち去れ!」"}
{"主体":"メロス","対象":"セリヌンティウス", "行動":"謝る", "発言":"「ごめんなさい、もうすぐ返します」"}
{"主体":"メロス", "対象":"周りの人々", "行動":"困惑する", "発言":"「なんでこんなに怒ってるんだ……?」"}
{"主体":"周りの人々", "対象":"セリヌンティウス", "行動":"説得する", "発言":"「そんなに怒らなくてもいいじゃないですか。どうかおだまりください」"}

周りの人々って誰だよ……?

結果その2

{"主体":"セリヌンティウス","対象":"メロス", "行動":"謝罪する", "発言":"「ああ、すまなかった。明日返すよ」"}
{"主体":"メロス","対象":"セリヌンティウス", "行動":"冷静に対応する", "発言":"「それはすまなかった。もし返済期限が来ている場合は、もう一度お伺いします」"}
{"主体":"セリヌンティウス","対象":"メロス", "行動":"納得する", "発言":"「そうか。俺も返すのを忘れたことがあったから、大丈夫だよ。また味噌汁作ってくれたら返すからね」"}
{"主体":"メロス","対象":"セリヌンティウス", "行動":"冷静に対応する", "発言":"「それはすまなかった。もし返済期限が来ている場合は、もう一度お伺いします」"}
{"主体":"セリヌンティウス","対象":"メロス", "行動":"感謝する", "発言":"「ありがとう。大丈夫だよ、返済期限が来ているわけではないから。今度は俺がおごるから、飲みに行こうぜ」"}
{"主体":"セリヌンティウス","対象":"メロス", "行動":"再度感謝する", "発言":"「大丈夫だよ、そんなことないよ。また今度返せばいいから、気にしないで。お互いにいい日になるように祈ってるよ」"}
{"主体":"セリヌンティウス","対象":"メロス", "行動":"返金する", "発言":"「ごめん、すぐに返すよ」と言って、10円を渡した。"}
{"主体":"メロス","対象":"セリヌンティウス", "行動":"笑って返す", "発言":"「ありがとう、どうせ気にしてなかったんだけどね。ここはお返しに、今度は味噌汁を作るから楽しみにしてて」"}
{"主体":"メロス","対象":"セリヌンティウス", "行動":"受け取り、一礼する", "発言":"「ありがとう、でも返さなくてもいいよ。俺も今度はセリヌンティウスに何かお返しするから待っててね」"}
{"主体":"メロス","対象":"セリヌンティウス", "行動":"受け取り、手を握り返す", "発言":"「ありがとう、でも本当に必要ならいつでも返してね。お互いに支え合っていこうよ」"}

メロスとセリヌンティウスが交互に行動・発話をしてほしいのに、セリヌンティウスが連続したりメロスが連続したりする。

今回の失敗

今回の失敗というか、前回から引き続き思っていることなのだが、登場人部はクラスを設けて管理したほうが良いと思う。

ここから先は

0字

¥ 9,000

この記事が気に入ったらサポートをしてみませんか?