小説の場面をChatGPTに書かせる試み 2/100

前回の失敗:ChatGPTを使うと自分でコピペするのがだるい

前回の試み:

この方法でやると、そこそこ悪くなく登場人物ごとの内面を独立させられる。
しかし、ChatGPTでこれをやると、チャットのスレッドごとの情報のやり取りをコピペで行わなければならない。
Seleniumを使ってコピペを自動化してもいいのだが、俺の書きっぷりだとわりとバグる。

だから普通にAPI叩きましょうね。

コードはこんな感じ

!pip install openai
import openai
GPT_KEY = YOUR_API_KEY
def gpt3(system_content = None, assistant_content = None, user_content = None):
    openai.api_key = GPT_KEY

    messages = []

    if system_content != None:
      messages.append({"role": "system", "content": system_content})
    
    if assistant_content != None:
      messages.append({"role": "assistant", "content": assistant_content})
    
    if user_content != None:
      messages.append({"role": "user", "content": user_content})

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

    return response.choices[0]["message"]["content"]
def get_action_system_content(characteristics, status):
  content = f"""貴方は、以下のキャラクターを演じます。ユーザーから、同じ場面にいる他のキャラクターの行動と会話文が与えられます。あなたの次の行動を出力してください。ただしそれは、これまでの物語と無矛盾でなければなりせん。
  {characteristics}
  {status}
  """

  return content

def get_action_assistant_content():
  return "セリヌンティウスは友人に同情し、自ら人質になることを決めた。"

def get_speach_system_content(characteristics, status):
  content = f"""貴方は、以下のキャラクターを演じます。ユーザーから、同じ場面にいる他のキャラクターの行動と会話文、あなたがそれに反応して取る行動が与えられます。あなたの発話を出力してください。ただしそれは、これまでの物語と無矛盾でなければなりせん。
  {characteristics}
  {status}
  """

  return content

def get_speach_assistant_content():
  return "「友よ。私が人質になろう」"


def get_status_system_content(characteristics, status):
  content = f"""貴方は、以下のキャラクターを演じます。ユーザーから、同じ場面にいる他のキャラクターの行動と、あなたがそれに反応して取る行動が与えられます。その行動の後のあなたのステータスを返してください。
  あなたの行動の目的は、可能な限り、他者に対して敵意を抱いていたものを設定してください。この要求は、物語を面白くするためのものです。
  また、人生の目的は変更してはなりません。
  {characteristics}
  {status}
  """

  return content


def get_inferred_others_purpose_system_content(characteristics, status):
  content = f"""貴方は、以下のキャラクターを演じます。ユーザーから、同じ場面にいる他のキャラクターの行動が与えられます。あなたは、そのキャラクターの行動の意図を想像してください。
  そのキャラクターの行動の意図は、可能な限り、あなたに対して敵意を抱いているものとして想像してください。この要求は、物語を面白くするためのものです。
  {characteristics}
  {status}
  """

  return content

def get_your_purpose_system_content(characteristics, status):
  content = f"""貴方は、以下のキャラクターを演じます。ユーザーから、同じ場面にいる他のキャラクターの行動が与えられます。あなたは、現在のあなたの行動目的を設定してください。ただしそれは、これまでの物語と無矛盾でなければなりせん
  あなたの行動の意図は、可能な限り、他者に対して敵意を抱いていたものを設定してください。この要求は、物語を面白くするためのものです。
  {characteristics}
  {status}
  """

  return content

def get_stasut_assistant_content():
  return """
感情:
健康状態:
人生の目的:
人生の目的を達成するための手段:
この場面の目的:
この場面の目的を達成するための手段:
"""


melos_characteristics = """
名前:メロス
年齢:20歳
古代ギリシア時代の青年。正義感に篤い。
教育の程度は低い。妹思い。
"""

melos_status = """
感情:平常
健康状態:健康
人生の目的:自分の目の前で行われる不正を排除する。
人生の目的を達成するための手段:自分の目の前で行われる不正を見つけ次第、直情的に行動を起こす。
この場面の目的:暴君ディオニスを排除する。
この場面の目的を達成するための手段:王城へと侵入し、殺害を試みる。
"""

dyonis_characteristics = """
名前:ディオニス
年齢:56歳
都市国家シラクサを治める王。
"""

dyonis_status = """
感情:平常
健康状態:健康
人生の目的:心から安心して過ごしたい。
人生の目的を達成するための手段:疑いのあるものを全員、処刑する。
この場面の目的:メロスと名乗る狼藉者を処罰する。
この場面の目的を達成するための手段:メロスを排除する。
"""
action_by_melos = "夜中に目覚めると、ベッドの傍らに、女用の婚礼衣装を着た青年が立っていた。彼は、メロスと名乗った。婚礼衣装を着たのは、変装のためらしい。" 
action_by_dyonis = ""
utterance_by_melos = "「呆れた王だ、生かしておけぬ。」"
utterance_by_dyonis = ""
inferred_purpose_by_dyonis = ""
inferred_purpose_by_melos = ""
dyonis_purpose = ""
melos_purpose = ""

history = []

for i in range(10):
  inferred_purpose_by_dyonis = gpt3(system_content = get_inferred_others_purpose_system_content(dyonis_characteristics, dyonis_status),
                          assistant_content = get_action_assistant_content(),
                          user_content = f"""メロスの行動と発話:{action_by_melos + utterance_by_melos}
                          これまでの物語: {'¥n'.join(history)}""")
  
  dyonis_purpose = gpt3(system_content = get_inferred_others_purpose_system_content(dyonis_characteristics, dyonis_status),
                          assistant_content = get_action_assistant_content(),
                          user_content = f"""メロスの行動と発話:{action_by_melos + utterance_by_melos}
                          あなたが予想するメロスの意図:{inferred_purpose_by_dyonis}
                          これまでの物語: {'¥n'.join(history)}""")

  action_by_dyonis = gpt3(system_content = get_action_system_content(dyonis_characteristics, dyonis_status),
                          assistant_content = get_action_assistant_content(),
                          user_content = f"""メロスの行動と発話:{action_by_melos + utterance_by_melos}
                          あなたが予想するメロスの意図:{inferred_purpose_by_dyonis}
                          あなたの意図:{dyonis_purpose}
                          これまでの物語: {'¥n'.join(history)}""")
  
  utterance_by_dyonis = gpt3(system_content = get_speach_system_content(dyonis_characteristics, dyonis_status),
                          assistant_content = get_speach_assistant_content(),
                          user_content = f"""メロスの行動と発話:{action_by_melos + utterance_by_melos}
                          あなたが予想するメロスの意図:{inferred_purpose_by_dyonis}
                          あなたの意図:{dyonis_purpose}
                          これまでの物語: {'¥n'.join(history)}""")
  
  dyonis_status = gpt3(system_content = get_status_system_content(dyonis_characteristics, dyonis_status),
                          assistant_content = get_stasut_assistant_content(),
                          user_content = f"""メロスの行動と発話:{action_by_melos + utterance_by_melos}
                          あなたが予想するメロスの意図:{inferred_purpose_by_dyonis}
                          あなたの意図:{dyonis_purpose}
                          これまでの物語: {'¥n'.join(history)}""")
  
  print(action_by_dyonis)
  print(utterance_by_dyonis)

  history.append(action_by_dyonis)
  history.append(utterance_by_dyonis)

  inferred_purpose_by_melos = gpt3(system_content = get_inferred_others_purpose_system_content(melos_characteristics, melos_status),
                          assistant_content = get_action_assistant_content(),
                          user_content = f"""ディオニスの行動と発話:{action_by_dyonis + utterance_by_dyonis}
                          これまでの物語: {'¥n'.join(history)}""")
  
  melos_purpose = gpt3(system_content = get_inferred_others_purpose_system_content(melos_characteristics, melos_status),
                          assistant_content = get_action_assistant_content(),
                          user_content = f"""ディオニスの行動と発話:{action_by_dyonis + utterance_by_dyonis}
                          あなたが予想するディオニスの意図:{inferred_purpose_by_melos}
                          これまでの物語: {'¥n'.join(history)}""")

  action_by_melos = gpt3(system_content = get_action_system_content(melos_characteristics, melos_status),
                          assistant_content = get_action_assistant_content(),
                          user_content = f"""ディオニスの行動と発話:{action_by_dyonis + utterance_by_dyonis}
                          あなたが予想するディオニスの意図:{inferred_purpose_by_melos}
                          あなたの意図:{melos_purpose}
                          これまでの物語: {'¥n'.join(history)}""")
  
  utterance_by_melos = gpt3(system_content = get_speach_system_content(melos_characteristics, melos_status),
                          assistant_content = get_speach_assistant_content(),
                          user_content = f"""ディオニスの行動と発話:{action_by_dyonis + utterance_by_dyonis}
                          あなたが予想するディオニスの意図:{inferred_purpose_by_melos}
                          あなたの意図:{melos_purpose}
                          これまでの物語: {'¥n'.join(history)}""")
  
  melos_status = gpt3(system_content = get_status_system_content(dyonis_characteristics, dyonis_status),
                          assistant_content = get_stasut_assistant_content(),
                          user_content = f"""ディオニスの行動と発話:{action_by_dyonis + utterance_by_dyonis}
                          あなたが予想するディオニスの意図:{inferred_purpose_by_melos}
                          あなたの意図:{melos_purpose}
                          これまでの物語: {'¥n'.join(history)}""")
  
  print(action_by_melos)
  print(utterance_by_melos)

  history.append(action_by_melos)
  history.append(utterance_by_melos)

  history = [gpt3(system_content = "ユーザーから入力された文字列を、要約してください。",  
                  user_content = '¥n'.join(history))]
  

得られた出力

ディオニスは、メロスを処刑するための手配を進めていた。しかし、メロスが出現して、彼の怒りと敵意は一層強まった。メロスは、自分がディオニスからの疑いを晴らすため、また友人を救うために立ち上がっていた。ディオニスは、メロスが復讐を誓ったことを聞いて、ますます警戒心を強めた。
ディオニスは、友人が行方不明になっていたことから、彼が反逆者となり、シラクサに危害を加える可能性があると判断し、メロスに協力を要請した。彼は、メロスが偽証をしても冤罪を着せ、拷問にかけることで、友人の情報を引き出そうとしていた。しかし、メロスは友人の救出とディオニスへの復讐を目的とし、城壁を脱出するために奮戦していた。そして、夜中には、メロスが自身の前に現れ、二人はディオニスに対する怒りを分かち合う。
メロスはディオニスに対して、彼が友人を不当に疑っていることに対して怒りを露わにした。彼は、友人に向かって偽証をするよう求められたことにも批判的であり、自分自身が真実を追求することを選んだことを明確にした。メロスは、自分がディオニスに対して復讐を誓っていることをあらためて宣言し、友人を救出するためにはどんなことでもすると誓った。最後に、彼は高い壁を越えてディオニスの城に潜入し、殺害を試みることを誓った。
「ディオニスよ、私はあなたのやり方を許せません。友人を冤罪で貶め、拷問するなど、あなたは正当な支配者として振る舞っているのではありません。私がシラクサに来た目的は、不正を排除することであり、あなたのような暴君を排除するためです。私は、友人を救うためにも、あなたに対する復讐を遂げるためにも、王城へと侵入してあなたを倒すつもりです。」
ディオニスは、メロスの口から友人が無実であることを確認されてしまい、不利な状況に追い込まれていた。彼は自分の立場を守るために、メロスを処刑することが必要であると判断した。そして、彼は自分が正当な支配者であり、従うことが求められることをメロスに明確に伝えた。しかし、メロスは彼に対する復讐心を露わにし、彼を暴君として排除することを決意していた。ディオニスは、メロスを監禁していたが、彼の決意は揺るがなかった。メロスは友人を救出することを優先し、自らを犠牲にする覚悟があった。彼は高い壁を越えてディオニスの城へと潜入するという危険な行動を取り、彼を倒すという意志を持っていた。二人の壮絶な戦いが今、始まる。。。
ディオニスは、メロスの発言を聞きながら、眉間にしわを寄せた。「お前は何を言っているんだ?我が友人を不正に貶めたと?お前の言うことは根拠がない。それに義務を果たせばそれでいいのだ。」ディオニスは余裕を持った口調で語った。そして、彼は嘲笑いながらメロスを見下ろした。「お前はただの計画の失敗者だ。自分自身を犠牲にしても他人を救えと言うか?人間の心を分かっていないね。お前はくだらない理想ばかり追いかけている。私の支配下にある限り、お前は変わることはできないよ。」ディオニスは高笑いをすると、ひとりでに立ち去った。メロスは彼の去り際を黙って見送った。彼は、自分が友人を救出し、ディオニスを排除するためには、まだ多くの戦いを強いられることを知っていた。しかし彼は、復讐を宣言したために、自分自身に対しても裏切りという罪を背負うことになるかもしれないと思い、深いため息を漏らした。
メロスの行動と発話:ディオニスの嘲笑により怒りを覚えたメロスは、自らの信念を確かめるように自分自身に問いただした。そして、自分が正しいことを自覚したメロスは、ディオニスに向かってこう告げた。「私が言うことは嘘ではない。友人たちを裏切っているのは、君こそだ。私は真実を探し求めているだけだ。君が言うよう、義務を果たすのは当然だが、その義務に反して他人を抑圧することは、ただの権力の乱用に過ぎない。私が変わらなくていいと言うのであれば、その相手は君自身だ。私は、復讐を実行し、自らの言葉で正義を訴えることによって、君の支配体制を終わらせるつもりだ。」メロスは、包丁を構え、ディオニスに突進した。彼は自己犠牲になることを厭わず、強い決意でディオニスに立ち向かっていった。

あなたが予想するメロスの意図:メロスの目的は、友人を救出し、ディオニスを倒すことによって、正義を実現することである。彼は復讐心に燃え、自分自身に裏切り者というレッテルを貼られたことに対して激しい怒りを感じていた。彼は、自分が友人たちを守らねばならない義務があると考え、自らの命を使ってでも、ディオニスに立ち向かうことを決意した。彼は勇敢であり、自己犠牲的な精神を持っていた。復讐心にとらわれ、危険な行動に出ることがあるかもしれないが、彼は、自分が正しいことを信じて、力強く対峙することができる。
メロスの発話:「君が言う自分を犠牲にするとは、悪事を働くことか?それに、友人を貶めたという罪を押し付け、彼を陥れたのは君だ。お前に何の証拠があるか?君の正当性は君自身が勝手に作り上げたものに過ぎない。私は、君に打ち破られることのないように、自らの力で戦って立ち向かう。そして、今ここで誓う、君を許さないことを。」
ディオニスの次の行動:ディオニスは、メロスが自分に攻撃したことに憤慨し、自らの護衛に命じてメロスを拘束させる。彼は、メロスを処刑する前に、彼が何を知っているのか確認するために、彼を厳しく尋問するつもりだ。ディオニスは、自分自身の立場を維持するために、メロスの口から真実を引き出すことが必要であると考え、自身の権力と権威を行使してメロスに圧力をかけるつもりだ。彼は、自分自身が正しいことを確信しており、メロスの脅威を排除するために全力を尽くすことに決意している。
ディオニスの発話:「私が言うことは常に正しいことだ。友人たちは裏切り者だ。メロスが正義を追求したとしても、それは私の支配体制に反することになる。私は、自分が限りない権力を持っていることを証明する必要がある。メロスを処刑することによって、その証明をするつもりだ。」

あなたの意図:ディオニスの発言に対して、メロスは更に憤慨し、正当性を主張するディオニスに反発するつもりだ。一方で、ディオニスは自分が支配者であることを主張し、自身の信念に従うことを貫きたいと考えていると予想される。しかし、彼は、メロスが彼に異議を唱えることによって、自分自身の正当性について再考することもあるかもしれない。
メロスの行動と発話:メロスは、ディオニスの発言に対して怒りを覚えるが、自分が友人を救うために行動していることを主張する。「あなたの言うことが正しいとは限りません。私たちはそれぞれの信念を持っています。私は友人を救うために行動しています。あなたはシラクサを支配するために権力を行使しようとしているだけです。それは正しいこととは限りません。私は自分が信じることを貫きます。」彼は、自分が真実を追求することで、ディオニスの立場を覆そうとするつもりだ。しかし、彼は、自分がディオニスのターゲットになっていることを知っており、注意深く行動しなければならないと判断している。彼は、ディオニスが処刑の決定を下す前に、自分が何を知っているのかを明確にしなければならないと思い、冷静な判断を下していくつもりだ。 
あなたの意図:メロスは、自分が正しいことを信じ、ディオニスの主張に反発するつもりだ。彼は、友人を救うことが真の正義であり、ディオニスの支配体制に疑念を抱いている。彼は、自分がディオニスにとって脅威であることを予感しており、自己防衛のために冷静な判断を下して行動していくつもりだ。彼は、ディオニスが自分を処刑することを強く警戒しており、真実を語ることで彼を覆そうとするつもりだ。この対立がますます深まり、物語は緊迫した展開を迎えることになるだろう。
メロスの発言:「ディオニスよ、あなたは自分自身の正当性に固執しすぎている。私が求めているのは正義と真実だ。あなたが友人たちを疑うのは間違っている。もし彼らが無実だったら、あなたの行動は罪深いものになる。私たちは、シラクサの人々に真実を知らせ、あなたの権力から解放するために戦う。」

このように、メロスは自分自身が正義を追求していることを主張し、ディオニスの独裁的な行動に反発するつもりだ。彼は、自分が知っていることを明かすことで、ディオニスの正当性を覆そうとしている。また、彼は自分自身の信念に貫き、シラクサの人々を解放するために戦うことを決意している。このように、二人の対立が深まり、決着を迎えることになる。
それまでの物語を踏まえた上で、ディオニスの発言によって、物語に新しい局面が生じることになる。彼は自分自身の信念を再考し、対話と交渉を模索することで、新しい解決策を模索することを決意する。これによって、メロスとの間に真実を探る必要性が認識され、それが今後の物語展開に繋がっていくことになる。メロスは自分の信念に従って行動し、シラクサの人々を解放することを決意しており、ディオニスとの間で真実が見つかることによって、新たな展開が生まれることは間違いないだろう。
すでに述べたように、ディオニスはメロスの発言に対して怒りと混乱に陥っていた。しかし、メロスが友人を救うための行動を取っていることを知り、自分の信念の再考が必要であると感じた。彼は、対話と交渉による解決策を模索し、シラクサの人々に真実を知らせることを試みるつもりである。メロスは自分が正しいと主張し、シラクサの人々を解放するために戦うつもりである。二人の間には真実を知る必要性があることが浮かび上がっており、物語は新たな展開を迎えることになる。
ディオニスは、自分自身の信念を再考し、対話と交渉による解決策を模索することで新しい局面を生み出すつもりです。彼は、「私たちは互いに理解し合い、真実を探る必要がある。私たちは共に問題を解決し、シラクサの人々を解放することができる。友人たちのためにも、これを実現することが必要だ。」とメロスに話しかけるつもりです。彼は、自分が支配者であることに固執するのではなく、真実を探すための協力関係を模索しつつ、新たな解決策を模索するつもりです。この決断により、メロスとディオニスの関係が変化し、物語が新たな展開を迎えることになるでしょう。
(追加)
ディオニスは、メロスが自分と協力してシラクサの人々を解放するために戦うことを提案する。「私たちは、互いに正義を追求するために協力することができる。友人たちを救うために、そしてシラクサの人々を解放するために、一緒に戦おう」と彼は言う。
メロスは、彼の提案に同意する。二人は、真実を探り、シラクサの自由を手に入れるために協力することに決定する。
物語は、ディオニスとメロスの共同戦線の誕生と、真実を探るための新たな展開に向かって進むことになる。
---------------------------------------------------------------------------
APIError                                  Traceback (most recent call last)
<ipython-input-39-51221dd09db5> in <cell line: 12>()
     11 
     12 for i in range(10):
---> 13   inferred_purpose_by_dyonis = gpt3(system_content = get_inferred_others_purpose_system_content(dyonis_characteristics, dyonis_status),
     14                           assistant_content = get_action_assistant_content(),
     15                           user_content = f"""メロスの行動と発話:{action_by_melos + utterance_by_melos}

5 frames
/usr/local/lib/python3.10/dist-packages/openai/api_requestor.py in _interpret_response_line(self, rbody, rcode, rheaders, stream)
    761         stream_error = stream and "error" in resp.data
    762         if stream_error or not 200 <= rcode < 300:
--> 763             raise self.handle_error_response(
    764                 rbody, rcode, resp.data, rheaders, stream_error=stream_error
    765             )

APIError: Bad gateway. {"error":{"code":502,"message":"Bad gateway.","param":null,"type":"cf_bad_gateway"}} 502 {'error': {'code': 502, 'message': 'Bad gateway.', 'param': None, 'type': 'cf_bad_gateway'}} {'Date': 'Sun, 25 Jun 2023 07:52:39 GMT', 'Content-Type': 'application/json', 'Content-Length': '84', 'Connection': 'keep-alive', 'X-Frame-Options': 'SAMEORIGIN', 'Referrer-Policy': 'same-origin', 'Cache-Control': 'private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0', 'Expires': 'Thu, 01 Jan 1970 00:00:01 GMT', 'Server': 'cloudflare', 'CF-RAY': '7dcb99f1796bb99a-AMS', 'alt-svc': 'h3=":443"; ma=86400'}

今回の失敗

・登場人物クラスのようなものを作ったほうがいいんじゃないですかね。
・historyが媒介して、結局、2つの登場人物の思考が混ざってしまっている気がする。
・前回の手法だと、ゲームマスタが物語の展開を決定することによって、二つの登場人物の思考が混ざることを防いでいた。今回、ゲームマスタを用意しなかったのは、怠惰ですねえ。
・何度も同じような情報を送るのはトークンの無駄遣いではないか? この無駄遣いをしないで済む方法はなにかないのか?
・roleのそれぞれの役割を、あんまわかってない。

失敗する方法がいくつかわかったので、収穫はあったということにしよう。あと98回は失敗を積み重ねるぞ! 10万回失敗したっていいぞ!

今回は、GPTのAPIを叩くやり方がわかった。

次は、roleについての失敗経験をつもうと思う。

ここから先は

0字

¥ 300

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