gpt-oss:20bに数当てゲームをプレイさせる

LLM界隈ではMCPサーバ実装が流行ってますね。

色々あるんですがゲーム実装もありますね。

 

select766.hatenablog.com

 

こちらはOpenAIのgpt-5を呼んだみたいです。

推定した数字に対する回答がMCPサーバで実装されています。

 

サーバ立てるのは面倒ということで、うちではgpt-oss:20bをOllamaのTool Calling機能で回答させる実装をしてみました。

見ての通り1ファイルに収まります。

叩き台はollama-pythonのexamplesにあるものを利用しました。

ollama-python/examples at main · ollama/ollama-python · GitHub

 

# Codex CLIに数当てゲームをプレイさせる(not 数当てゲームを実装させる)
import random
from typing import Iterator

from ollama import chat
from ollama._types import ChatResponse


def guess_the_number(number: int) -> str:
    """
    Send the guessed number.
    It will return one of the following: matches the correct answer, is greater than the correct answer, or is less than the correct answer.

    Args:
        number (int): The guessed number

    Returns:
        str: correct or greater or less
    """
    answer = 77 # The correct answer
    if (number == answer):
        return "correct"
    elif (number < answer):
        return "less than the answer"
    else:
        return "greater than the answer"


available_tools = {'guess_the_number': guess_the_number}

messages = [{'role': 'user', 'content': '数当てゲームをします。私が決めた数をあなたが当てます。数は整数で、1以上100以下です。tools"guess_the_number"に予想した数を送り、正しくなければほかの数を送ることを正解するまで繰り返してください。正解したら実行を終了してください。'}]


model = 'gpt-oss:20b'
# gpt-oss can call tools while "thinking"
# a loop is needed to call the tools and get the results
final = True
while True:
  print(messages)
  response_stream: Iterator[ChatResponse] = chat(model=model, messages=messages, tools=[guess_the_number], stream=True,
                                                 options={ "num_ctx": 32768 }
                                                 )

  for chunk in response_stream:
    if chunk.message.content:
      if not (chunk.message.thinking or chunk.message.thinking == '') and final:
        print('\nFinal result: ')
        final = False
      print(chunk.message.content, end='', flush=True)
    if chunk.message.thinking:
      print(chunk.message.thinking, end='', flush=True)

  print()

  if chunk.message.tool_calls:
    for tool_call in chunk.message.tool_calls:
      function_to_call = available_tools.get(tool_call.function.name)
      if function_to_call:
        print('\nCalling tool: ', tool_call.function.name, 'with arguments: ', tool_call.function.arguments)
        result = function_to_call(**tool_call.function.arguments)
        print('Tool result: ', result + '\n')

        messages.append(chunk.message)
        messages.append({'role': 'tool', 'content': result, 'tool_name': tool_call.function.name})
      else:
        print(f'Tool {tool_call.function.name} not found')

  else:
    # no more tool calls, we can stop the loop
    break

 

少々文言を厳しめにしたり、コンテキスト長を長くしたりしてあります。

gpt_ossが途中にどういう思考過程を経て回答に至るか出力されますので興味がある方は実行してみて下さい。

比較対象はもちろんgpt-5ですね。

GitHub - select766/codex-number-guess-game: Codex CLIに数当てゲームをさせる実験コード