はじめに
「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
はまりポイント
定義した関数の戻り値をlist形式にしています。そのままではエラーが出ました。
ToolMessageのcontentを文字列に変換する作業が必要でした。