书接上回

这是2024年5月29日的帖子,当时没认真实验完

curl -fsSL https://ollama.com/install.sh | sh

再更新一次

一个月都不到,疯狂刷版本的ollama

模型本身没有更新:

 https://ollama.com/library/mistral:7b-instruct-v0.3-q5_K_M 

curl http://localhost:11434/api/generate -d '{
  "model": "mistral",
  "prompt": "[INST] why is the sky blue? [/INST]",
  "raw": true,
  "stream": false
}'

先给mistral发一个请求激活一下模型

list了一下发现有点多

改改

curl http://localhost:11434/api/generate -d '{
  "model": "mistral:7b-instruct-v0.3-q5_K_M",
  "prompt": "[INST] why is the sky blue? [/INST]",
  "raw": true,
  "stream": false
}'

ok,拿到了返回了

接着继续

curl http://localhost:11434/api/generate -d '{
  "model": "mistral:7b-instruct-v0.3-q5_K_M",
  "prompt": "[AVAILABLE_TOOLS] [{\"type\": \"function\", \"function\": {\"name\": \"get_current_weather\", \"description\": \"Get the current weather\", \"parameters\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\", \"description\": \"The city and state, e.g. San Francisco, CA\"}, \"format\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"], \"description\": \"The temperature unit to use. Infer this from the users location.\"}}, \"required\": [\"location\", \"format\"]}}}][/AVAILABLE_TOOLS][INST] What is the weather like today in San Francisco [/INST]",
  "raw": true,
  "stream": false
}'

注意一下,就是里面的“我都做了转义

{"model":"mistral:7b-instruct-v0.3-q5_K_M","created_at":"2024-06-22T05:16:51.60371924Z",
"response":"[TOOL_CALLS] [{\"name\": \"get_current_weather\", 
\"arguments\": {\"location\": \"San Francisco, CA\", \"format\": \"celsius\"}}]",
"done":true,"done_reason":"stop","total_duration":1365854578,"load_duration":35952801,
"prompt_eval_count":137,"prompt_eval_duration":290965000,"eval_count":36,
"eval_duration":991440000}
[TOOL_CALLS] [{\"name\": \"get_current_weather\", 
\"arguments\": {\"location\": \"San Francisco, CA\", \"format\": \"celsius\"}}]


按官方文档来说,应该给我这个回复

[TOOL_CALLS] [{\"name\": \"get_current_weather\", 
\"arguments\": {\"location\": \"San Francisco, CA\", \"format\": \"celsius\"}}]

最后无误,这里其实就没啥问题了

===========================================

接下来上langchain

 mkdir mistral_tool_call_with_langchain
 cd mistral_tool_call_with_langchain
 python3 -m venv .venv
 source .venv/bin/activate
pip install langchain_community
pip install langchain_core
pip install langchain
pip install langchain_experimental
pip install -U duckduckgo-search
from langchain_experimental.llms.ollama_functions import OllamaFunctions
from langchain_core.messages import HumanMessage

model = OllamaFunctions(model="mistral:7b-instruct-v0.3-q5_K_M", format="json")

model = model.bind_tools(
    tools=[
        {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, " "e.g. San Francisco, CA",
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "The temperature unit to use. Infer this from the users location."
                    },
                },
                "required": ["location", "unit"],
            },
        }
    ],
    function_call={"name": "get_current_weather"},
)

res = model.invoke("what is the weather in Boston?")

print(res)

#content='' id='run-2d754254-223e-4f42-91f0-4a069f73f522-0' 
# tool_calls=[{'name': 'get_current_weather', 'args': {'location': 'Boston, MA', 'unit': 'celsius'}, 
# 'id': 'call_1674d88b6c1a40d9b25dccb5c4de45f9'}]

 https://python.langchain.com/v0.2/docs/integrations/chat/ollama_functions/ 


from langchain_experimental.llms.ollama_functions import OllamaFunctions
from langchain_core.messages import HumanMessage
from langchain_core.messages import AIMessage
from langchain_community.tools.ddg_search.tool import DuckDuckGoSearchRun
import json

search = DuckDuckGoSearchRun()

model = OllamaFunctions(model="mistral:7b-instruct-v0.3-q5_K_M", format="json")

model2 = OllamaFunctions(model="mistral:7b-instruct-v0.3-q5_K_M", format="json")

model = model.bind(
    functions=[
        {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, " "e.g. San Francisco, CA",
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                    },
                },
                "required": ["location"],
            },
        }
    ],
    function_call={"name": "get_current_weather"},
)

# 使用 JsonOutputToolsParser 来试图解析结果
# https://python.langchain.com/docs/modules/model_io/chat/function_calling#binding-functions

# tool_chain = model | JsonOutputToolsParser(name="get_current_weather")
# result = tool_chain.invoke("what is the weather in Boston?")
# print(result)
# 这个方法是废的,因为这是针对OpenAI的
def get_current_weather(location):
    res = "真的是在被call哦,get_current_weather:"+location
    print(res)
    result = search.run("what is the current weather in "+location)
    print(result)
    return result

result=model.invoke("what is the weather in xi'an?")

print(result.tool_calls)
cur_tool_calls = result.tool_calls

# 判断字符串是否是可调用的函数
#https://stackoverflow.com/questions/59912800/how-do-i-check-if-a-string-is-a-callable-name-in-python
function_call_name = cur_tool_calls[0]['name']
function_call_arguments = cur_tool_calls[0]['args']
print(function_call_arguments)

if callable(locals()[function_call_name]):
    print(f"{function_call_name} 是当前文件中可调用的函数。")
    location = function_call_arguments["location"]
    print("location:",location)
    res = eval(function_call_name)(location)
    result = model2.invoke(res+"\n\n 根据上下文,并且使用celsius作为单位,使用中文来总结,这个城市的天气是怎样的?")
    print("\n")
    print(result.content)
    print("\n")
else:
    print(f"{function_call_name} 不是当前文件中可调用的函数。")

紧接着是使用更OK的例子来调用搜索引擎并返回结果的例子

我现在忽然觉得,不需要微调,只需要用提示词工程来给一堆例子,就可以让ollama后面的引擎,给我调出来合适的工具了