Turns a Python function into dictionary in the OpenAI standard you can attach as a tool to a LLM request.
Project description
func2llmtool - Python function to LLM tool
Usage
from func2llmtool.core import FuncInfo # this library
import litellm # or other LLM library
fi = FuncInfo.from_func(my_function) # your def my_function()
litellm.completion(model='inference/mymodel', messages=[], tools=[fi()])
Installation
Install latest from the GitHub repository:
$ pip install git+https://github.com/NumesSanguis/func2llmtool.git
or from pypi
$ pip install func2llmtool
Documentation
- Documentation (in a nicer format) can be found hosted on this GitHub repository’s pages.
- Package manager specific guidelines on pypi.
- Find the code at: github.com/NumesSanguis/func2llmtool
How to use
Let’s turn our weather function into a tool a LLM can use. The default output format is “litellm”. Supported:
# define our tool function with docstring and variable annotations
def get_weather(
city: str # City name
) -> str: # Returns the weather in a city, e.g. "rainy"
"""Get the current weather for a city."""
if city.lower() == "tokyo": weather = "sunny"
elif city.lower() == "amsterdam": weather = "cloudy"
else: weather = "rainy"
return weather
Extract the required data:
fi = FuncInfo.from_func(get_weather)
fi # same as print(fi)
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city. Return type: string (Returns the weather in a city, e.g. \"rainy\")",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name"
}
},
"required": [
"city"
],
"additionalProperties": false
}
}
}
Return the data without pretty printing:
fi() # same as: fi.to_tool_dict()
{'type': 'function',
'function': {'name': 'get_weather',
'description': 'Get the current weather for a city. Return type: string (Returns the weather in a city, e.g. "rainy")',
'parameters': {'type': 'object',
'properties': {'city': {'type': 'string', 'description': 'City name'}},
'required': ['city'],
'additionalProperties': False}}}
Format output dict according to OpenAI standard:
fi.to_tool_dict(format="openai")
{'type': 'function',
'name': 'get_weather',
'description': 'Get the current weather for a city. Return type: string (Returns the weather in a city, e.g. "rainy")',
'parameters': {'type': 'object',
'properties': {'city': {'type': 'string', 'description': 'City name'}},
'required': ['city'],
'additionalProperties': False},
'strict': True}
We can also provide the function name as long as it is in your Python globals:
FuncInfo.from_func('get_weather')()
{'type': 'function',
'function': {'name': 'get_weather',
'description': 'Get the current weather for a city. Return type: string (Returns the weather in a city, e.g. "rainy")',
'parameters': {'type': 'object',
'properties': {'city': {'type': 'string', 'description': 'City name'}},
'required': ['city'],
'additionalProperties': False}}}
Other docstring styles - Numpy
# define our tool function with numpy-style docstring
def get_weather_numpy_style(city: str) -> str:
"""
Get the current weather for a city.
Parameters
----------
city : str
City name
Returns
-------
str
The weather in a city, e.g. "rainy"
"""
if city.lower() == "tokyo": weather = "sunny"
elif city.lower() == "amsterdam": weather = "cloudy"
else: weather = "rainy"
return weather
FuncInfo.from_func(get_weather_numpy_style)()
{'type': 'function',
'function': {'name': 'get_weather_numpy_style',
'description': 'Get the current weather for a city. Return type: string (The weather in a city, e.g. "rainy")',
'parameters': {'type': 'object',
'properties': {'city': {'type': 'string', 'description': 'City name'}},
'required': ['city'],
'additionalProperties': False}}}
LiteLLM example - Attach tool info to LLM
Here we show how to attach the tool info to a LLM request, handle its tool request, return our tool output, and get our question about the weather answered.
import os
import litellm
from litellm.caching.caching import Cache
# set ENV variables for LLM usage; https://console.groq.com/keys
# os.environ["GROQ_API_KEY"] = "your-api-key"
Prepare our LLM call:
# groq is a fast inference provider (not to be confused with grok by X), which offers a free tier
MODEL = 'groq/llama-3.1-8b-instant' # any model supported by LiteLLM and for which you set a key
MESSAGES = []
TOOLS = [fi()]
litellm.cache = Cache(type="disk")
litellm.suppress_debug_info = True # prevent "Provider List: https://docs.litellm.ai/docs/providers" spam
# optional instructions
# MESSAGES.append({"role": "system", "content": "Use the results from tool calls to answer questions."})
MESSAGES.append({"role": "user", "content": "What is the weather in city Tokyo?"})
Call model with our Python function available as tool:
resp = litellm.completion(model=MODEL, messages=MESSAGES, tools=TOOLS, caching=True)
print(resp.choices[0].message.model_dump())
{'content': None, 'role': 'assistant', 'tool_calls': [{'function': {'arguments': '{"city":"Tokyo"}', 'name': 'get_weather'}, 'id': 'hjgzy4gz9', 'type': 'function'}], 'function_call': None, 'provider_specific_fields': None}
Note the
'tool_calls': [{'function': {'arguments': '{"city":"Tokyo"}', 'name': 'get_weather'}, ...
part. This is the tool call that the LLM made. Let’s execute it and
inform the LLM.
# example only shows how to handle 1 tool call (multiple can be requested in parallel)
tc = resp.choices[0].message.tool_calls[0]
tc
ChatCompletionMessageToolCall(function=Function(arguments='{"city":"Tokyo"}', name='get_weather'), id='hjgzy4gz9', type='function')
# The id associated to the tool call, so the LLM knows which output is associated to which tool call
tc.id
'hjgzy4gz9'
# The arguments are a JSON string, so we need to convert them before calling our function
import json
func_args = json.loads(tc.function.arguments)
func_args
{'city': 'Tokyo'}
Add tool call and usage to message history:
# keep track of the tool call by the LLM in our message history
MESSAGES.append({k:v for k,v in resp.choices[0].message.model_dump().items() if v is not None})
# Add tool call result to message history
MESSAGES.append({'role': 'tool', 'tool_call_id': tc.id, 'content': get_weather(**func_args)})
# We now have all info to query the LLM again
print(MESSAGES)
[{'role': 'user', 'content': 'What is the weather in city Tokyo?'}, {'role': 'assistant', 'tool_calls': [{'function': {'arguments': '{"city":"Tokyo"}', 'name': 'get_weather'}, 'id': 'hjgzy4gz9', 'type': 'function'}]}, {'role': 'tool', 'tool_call_id': 'hjgzy4gz9', 'content': 'sunny'}]
Give our LLM back the tool execution results and ask it to answer our initial question.
resp2 = litellm.completion(model=MODEL, messages=MESSAGES, tools=TOOLS, caching=True)
print(resp2.choices[0].message.content)
It's currently sunny in Tokyo.
Alternatives to this library
# LiteLLM has a build-in function, but it is not as flexible what is supported.
# Note the missing parameter description and nothing about what's returned
litellm.utils.function_to_dict(get_weather)
{'name': 'get_weather',
'description': 'Get the current weather for a city.',
'parameters': {'type': 'object',
'properties': {'city': {'type': 'string'}},
'required': ['city']}}
# gets the 'city' description, but nothing about what's returned
litellm.utils.function_to_dict(get_weather_numpy_style)
{'name': 'get_weather_numpy_style',
'description': 'Get the current weather for a city.',
'parameters': {'type': 'object',
'properties': {'city': {'type': 'string', 'description': 'City name'}},
'required': ['city']}}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file func2llmtool-0.0.2.tar.gz.
File metadata
- Download URL: func2llmtool-0.0.2.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c88adee2eaecbdd3df347c5f08b4540eea3adf4ef59c8ea6b2ca6a23062e37aa
|
|
| MD5 |
035fc1e19d8e1bfab6f8d60447499adb
|
|
| BLAKE2b-256 |
f7d0deae885f60fa36c8e2993c33c1d4358edaee9e976d22f73e9e5ecdd45547
|
File details
Details for the file func2llmtool-0.0.2-py3-none-any.whl.
File metadata
- Download URL: func2llmtool-0.0.2-py3-none-any.whl
- Upload date:
- Size: 16.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94927427d1c7485a47c0e046252f0cbdb43486ac8b999e2b9f1c52ea61715380
|
|
| MD5 |
944aa55e203c582d00f7604271b07f7b
|
|
| BLAKE2b-256 |
1c1ee1f12f07f54ff31f913fd88c757b7d85559a4cd4aab9bf9d968a871e4567
|