以下の内容はhttps://touch-sp.hatenablog.com/entry/2025/02/01/152411より取得しました。


Mistral AIが「Mistral Small 3」を公開してくれたのでFunction Callingを使ってみました

はじめに

「Mistral Small 3」はOllamaから使えます。

4桁の数字に四則演算を追加して10を作る問題を解かせてみたのですが残念ながら解けませんでした。

今回はFunction Callingを使ってインチキしてみます。

使用したPC

プロセッサ	Intel(R) Core(TM) i7-12700H
実装 RAM	32.0 GB
GPU		RTX 3080 Laptop (VRAM 16GB)
Python 3.12
CUDA 12.4

Python環境

langchain==0.3.17
langchain-core==0.3.33
langchain-ollama==0.2.3
ollama==0.4.7

Pythonスクリプト

from langchain_core.messages import HumanMessage, SystemMessage, ToolMessage
from langchain_ollama import ChatOllama
from langchain.tools import tool
from itertools import product

model = ChatOllama(model="mistral-small:latest", temperature=0)

# ツールとしての関数を定義
@tool
def solve_puzzle(numbers: list[int]) -> list[str]:
    """4桁の数字の間に四則演算を加えて10を作るパズルを解く関数。

    Args:
        numbers (list[int]): 4つの数字のリスト

    Returns:
        list[str]: 10になる数式のリスト
    """
    operators = ['+', '-', '*', '/']
    expressions = []

    # すべての演算子の組み合わせを試す
    for ops in product(operators, repeat=3):

        patterns = [
            f"{numbers[0]} {ops[0]} {numbers[1]} {ops[1]} {numbers[2]} {ops[2]} {numbers[3]}",
            f"({numbers[0]} {ops[0]} {numbers[1]}) {ops[1]} {numbers[2]} {ops[2]} {numbers[3]}",
            f"({numbers[0]} {ops[0]} {numbers[1]} {ops[1]} {numbers[2]}) {ops[2]} {numbers[3]}",
            f"({numbers[0]} {ops[0]} {numbers[1]}) {ops[1]} ({numbers[2]} {ops[2]} {numbers[3]})",
            f"{numbers[0]} {ops[0]} ({numbers[1]} {ops[1]} {numbers[2]}) {ops[2]} {numbers[3]}",
            f"{numbers[0]} {ops[0]} ({numbers[1]} {ops[1]} {numbers[2]} {ops[2]} {numbers[3]})",
            f"{numbers[0]} {ops[0]} {numbers[1]}) {ops[1]} ({numbers[2]} {ops[2]} {numbers[3]})"
        ]

        for exp in patterns:
            try:
                if eval(exp) == 10:
                    expressions.append(exp)
            except:
                continue
    
    return expressions

tools_list = [solve_puzzle]

model_with_tools = model.bind_tools(tools_list)

messages = [
    SystemMessage(content="あなたは優秀なAIアシスタントです。日本語で回答して下さい。")
]

query = '''「9 9 9 9」という4桁の数字があります。数字と数字の間に四則演算の記号を追加して計算結果が10になるようにして下さい。
数字と数字の間に少数点を追加することは禁止されています。
隣あう数字をまとめて2桁以上の数字とみなすことは禁止されています。
括弧を使うことは可能です。

以下に例を示します。
~~~
「1 2 3 4」なら1+2+3+4が解答の一例です。
「4 5 4 2」なら(4*5)/(4-2)が解答の一例です。
~~~'''
messages.append(HumanMessage(content=query))

ai_message = model_with_tools.invoke(messages)

if len(ai_message.tool_calls) == 0:
    print(f"result: {ai_message.content}")

else:
    #print(ai_message.tool_calls)

    for tool_call in ai_message.tool_calls:
        selected_tool = {"solve_puzzle": solve_puzzle}[tool_call["name"].lower()]
        tool_msg = selected_tool.invoke(tool_call)
        messages.append(ToolMessage(content=str(tool_msg.content), tool_call_id=tool_call['id']))
    
    result = model_with_tools.invoke(messages)
    print(result.content)

結果

プロンプト

「9 9 9 9」という4桁の数字があります。数字と数字の間に四則演算の記号を追加して計算結果が10になるようにして下さい。
数字と数字の間に少数点を追加することは禁止されています。
隣あう数字をまとめて2桁以上の数字とみなすことは禁止されています。
括弧を使うことは可能です。

以下に例を示します。
~~~
「1 2 3 4」なら1+2+3+4が解答の一例です。
「4 5 4 2」なら(4*5)/(4-2)が解答の一例です。
~~~

回答

以下に「9 9 9 9」という数字を使って計算結果が10になるようにした例を示します。

  • (9 + 9 * 9) / 9
  • (9 * 9 + 9) / 9
これらの式は、与えられた制約に従って計算結果が10になります。

はまりポイント

定義した関数の戻り値をlist形式にしています。
そのままではエラーが出ました。
ToolMessageのcontentを文字列に変換する作業が必要でした。

関連記事

touch-sp.hatenablog.com





以上の内容はhttps://touch-sp.hatenablog.com/entry/2025/02/01/152411より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14