1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Hello World あたたたた OpenAI Responses API編

Posted at

この記事は Hello World あたたたた Advent Calendar 2025 の記事です。

今日は OpenAIのResponses APIを使って Hello World あたたたた を実装して解説していきます。

そもそも「Hello World あたたたた」が何かは 1日目の記事 をご覧ください。

やりたかったこと

ロジックをコードで書かなくても、ブラックボックス的に生成AIが処理して結果を返してくれれば、「あたたたた」ができるじゃないかと考えたのでやってみました。

ロジック中の 「あ」「た」生成「あたたたた」判定 をOpenAIのAPIにやってもらいます。

変数 hako に空文字をセット
変数 running に true をセット
running が true なら繰り返す
    0か1をランダムに決める  ← 「あ」か「た」をLLMでランダムに決めてもらう
    もし0なら
        変数 char に「あ」をセット
    その他なら
        変数 char に「た」をセット
    画面に char を出力
    char を hako に追加
    もし 最後の 5 文字が「あたたたた」なら   ← 最後の文字が「あたたたた」かをLLMで判定してもらう
        "お前はもう死んでいる" を出力
        running に false をセット        

コーディング例

import openai

# OpenAI APIキーを設定
openai.api_key = "NNNNNNNNNN"  # ←ご自身のAPIキーに置き換えてください

def generateATa():
    response = openai.responses.create(
        model="gpt-4o",
        input="Please reply あ or た randomly"
    )
    return response.output_text

def initAtatatata():
    response = openai.responses.create(
        model="gpt-5.2",
        input="I say a word like あたたあたたたた. If the last 5 words is あたたたた, answer お前はもう死んでいる. Otherwise, say ド.",
    )
    return response.output_text, response.id

def checkAtatatata(word, previous_response_id):
    response = openai.responses.create(
        model="gpt-5.2",
        input=word,
        previous_response_id=previous_response_id
    )
    return response.output_text, response.id

output_text, previous_response_id_for_checkAta = initAtatatata()
print(output_text)
print("-- inited --")

hako = ""

for i in range(100):
    char = generateATa()
    hako += char
    output_text, previous_response_id_for_checkAta = checkAtatatata(hako, previous_response_id_for_checkAta)
    print(char + " -> " + output_text)
    if(output_text == "お前はもう死んでいる"):
        break

実行結果

何度か実行しましたが、うまくいったり、うまくいなかったりばらつきがあります。

実行結果 うまくいったケース

「あ」と「た」をランダムに出力、「あたたたた」の並びも想定通りに判定できています。

ド
-- inited --
あ -> ド
あ -> ド
た -> ド
た -> ド
あ -> ド
た -> ド
あ -> ド
た -> ド
た -> ド
た -> ド
た -> お前はもう死んでいる

実行結果 うまくいかなかったケース

「あたたたた」判定の評価結果、レスポンスがおかしくなっています。「ド」がたくさん出たり、文末に「。」がつくのが解せない。

ド
-- inited --
あ -> ド
あ -> ド
あ -> ド
あ -> ドド
あ -> ドドドド
あ -> ド
あ -> ド
た -> ド
た -> ドドドド
あ -> ドドドドドドドドドドドドドドドドドドドド
た -> ドドドドドドドドドドドド。
あ -> ド。
た -> お前はもう死んでいる。
た -> ド。
た -> お前はもう死んでいる。
あ -> ド。
あ -> ド。

考察

モデルの気分(=確率的挙動)やpromptのあいまいさが原因と考えています。
まずはpromptをより厳密なもの(例:「必ず1文字だけ返せ。余計な文字は禁止」)にすることが改善の一手になりそう。
またJSON形式でresponseを返す(JSONモード)ようにすれば、responseがより安定するんじゃないかと予想してますが、試せていない。

コードの解説

「あ」か「た」のランダムな生成

def generateATa():
    response = openai.responses.create(
        model="gpt-4o",
        input="Please reply あ or た randomly"
    )
    return response.output_text
  • gpt-4o に「あ or た をランダムに返して」と頼んで、返答文字を返す

「あたたたた」判定ルールの定義

def initAtatatata():
    response = openai.responses.create(
        model="gpt-5.2",
        input="I say a word like あたたあたたたた. If the last 5 words is あたたたた, answer お前はもう死んでいる. Otherwise, say ド.",
    )
    return response.output_text, response.id
  • gpt-5.2 に「入力された文字列の末尾が あたたたた なら お前はもう死んでいる、違うなら 」という“判定ルール”を与える
  • その response の id を保存する(後続で会話状態をつなぐため)

「あたたたた」判定実行

def checkAtatatata(word, previous_response_id):
    response = openai.responses.create(
        model="gpt-5.2",
        input=word,
        previous_response_id=previous_response_id
    )
    return response.output_text, response.id
  • previous_response_id を渡して、同じ会話スレッドの続きとして word(あ or た) を送り、判定結果を返させる

ループ回数上限

  • for i in range(100): 終了条件を満たさない可能性があるので無限ループしないようにループは最大100回にしています

OpenAI API

OpenAIのAPI呼び出し部分を解説します。
以下のAPIを使っています。
Responses | OpenAI API Reference

def checkAtatatata(word, previous_response_id):
    response = openai.responses.create(
        model="gpt-5.2",
        input=word,
        previous_response_id=previous_response_id
    )
    return response.output_text, response.id

previous_response_id の意味

previous_response_id は、Responses API で「前の応答を参照して会話状態を引き継ぐ」ための仕組みです。これにより、initAtatatata() で与えた判定ルールが引き継がれて、次の checkAtatatata() でも使われます。
ただし前のことを記憶しているのでトークン数はどんどん増えていき、つまりお金もかかります。
このトークン消費を抑えるために、前の会話を要約してinputに入れる、過去の入力履歴を保存しておいて直近数件だけinputにする、などの工夫が実務では必要なようです。

モデルの指定

model="gpt-5.2"でモデルを指定します。
いろんなモデルを試した結果、ランダムは gpt-4o、判定は gpt-5.2 が結果が安定して、速度も出たのでそれぞれこれらのモデルを使っています。
このあたりのモデルの選択はなにかノウハウがあるのかもしれない。

個人的なコメント

狙ったことができたけど、結果が安定しません。いろいろ改善が必要そうです。
厳密なプロンプト、結果のチェックなどで安定して稼働させることができるんじゃないかと思います。
あと、生成AIで処理するとこのケースでは明らかにコストが高いです。時間がかかるしトークンを消費する(=お金もかかる)し、裏側で生成AIを回す電気も浪費しています。
ただ、もっと複雑であいまいな判定をさせるようなケースでは、コーディングの手間がなくなることで、このやり方でもコストメリットはでてくるかもしれないです。
かなり雑に作って雑な評価したけど、とりあえず動くものが作れました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?