Skip to main content

A lightweight Python library that simplifies the process of exposing functions as tools for Large Language Models

Project description

PyToolsmith

A lightweight Python library that simplifies the process of exposing functions as tools for Large Language Models.

Status

Tests PyPI - Version codecov

What is this?

LLM Tooling (or function calling) is a powerful way to connect LLMs to the real world. However, defining tool definitions can be cumbersome, as it requires defining both the tool function, and a JSON schema that describes the tool. Additionally, in some cases, you may want to control certain parameters passed into tools rather than have the LLM decide what to pass in. PyToolsmith aims to solve this by providing a simple API to define tools from function definitions and automatically generate the JSON schema to pass to the LLM.

Features

  • Generates JSON schemas directly from your function definitions.
  • Parses Google-style docstrings to describe your tools in the schema.
  • Pass the same tools into different LLM providers with a simple method call.
  • Define custom type mappings to extend functionality.

Supported Provider Interfaces

  • Anthropic
  • AWS Bedrock
  • OpenAI

Included Type Support

Part of being able to define schemas is mapping certain types to a JSON-compatible format. As such, PyToolsmith allows you to define custom type maps to be used to generate the JSON schema. However, it comes out-of-the-box with support for:

  1. Standard based objects str, int, float, bool, etc.
  2. UUIDs

Usage

Simply define a tool definition as such:

from pytoolsmith import ToolDefinition


# 1. Define your function
def my_tool(my_param: str | None, my_controlled_param: str = "hello") -> str:
    """
    This a tool that formats a specific string with parameters.
   
    Args:
       my_param: A parameter controlled by the LLM
       my_controlled_param: A parameter controlled by the application.
       
    Returns: A formatted string.
    """
    return f"I did a search for {my_param} with controlled parameter {my_controlled_param}!"


# 2. Make a tool definition, calling out the injected parameter.
tool_definition = ToolDefinition(function=my_tool, injected_parameters=["my_controlled_param"])

# 3. Get a schema representing the tool automatically
schema = tool_definition.build_json_schema()

# 4. Get a tool definition ready to pass directly into LLM calls. 
# Note that the LLM does not have the context for the controlled parameter.
schema.to_openai()
schema.to_anthropic()
schema.to_bedrock()

# Bedrock Output:
# {
#     "name": "my_tool",
#     "inputSchema": {
#         "json": {
#             "type": "object",
#             "properties": {
#                 "my_param": {
#                     "anyOf": [{"type": "string"}, {"type": "null"}],
#                     "description": "A parameter controlled by the LLM",
#                 }
#             },
#             "required": ["my_param"],
#         }
#     },
#     "description": "This a tool that formats a specific string with parameters. Returns: A formatted string.",
# }

Additionally, you can use the ToolLibrary class to make it easy to pass in a list of tools directly to your LLM call.

# ^ continuing from above
from pytoolsmith import ToolLibrary

# Make a library:
tool_library = ToolLibrary()
tool_library.add_tool(tool_definition)
tool_library.add_tool(other_tool_definition)

# Get a tool list ready to pass directly into LLM calls.
tool_library.to_openai()
tool_library.to_anthropic()
tool_library.to_bedrock()
# All of these are a list that can be passed in directly to your LLM call.

When you implement your LLM call, you can use the tool library to get the tool list, and call it directly.

# ^ continuing from above
hardset_parameters = {"tenant_id": "1234"}

# Get the tool name and parameters from the LLM call
llm_result = call_llm(
    "Can you help me look up my account? My name is John Doe",
    tools=tool_library
)

llm_params, tool_name = parse_llm_result(llm_result)

tool = tool_library.get_tool_from_name(tool_name)

tool_result = tool.call_tool(llm_parameters=llm_params, library_parameters=hardset_parameters)

# Result is ready to be passed back to the next LLM call.

Additionally, you can control the serialization parameters:

from bson import ObjectId
from pytoolsmith import pytoolsmith_config

pytoolsmith_config.update_type_map({ObjectId: "string"})

Future Plans

  • Extendable serialization support (for LLM messages -> function inputs and vise versa)

A Note

I was heavily inspired by FastAPI's batteries-included ability to create automatic OpenAPI specs for web applications. Having a single source of truth for your API docs defined as code speeds up development and reduces the chance of errors - why not apply that to LLM interfaces? 🤠

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytoolsmith-0.1.3.tar.gz (37.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytoolsmith-0.1.3-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

Details for the file pytoolsmith-0.1.3.tar.gz.

File metadata

  • Download URL: pytoolsmith-0.1.3.tar.gz
  • Upload date:
  • Size: 37.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.5

File hashes

Hashes for pytoolsmith-0.1.3.tar.gz
Algorithm Hash digest
SHA256 ba453f58082f4d52c276c5ffc48068181c9b038b7f80d807ce8d1c32998e3450
MD5 416a038d9a780992f8e3b02366ff532f
BLAKE2b-256 1349bee46fa4e3a868c9384a8f31f02669cb3ea5016183374257c36fe4450051

See more details on using hashes here.

File details

Details for the file pytoolsmith-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for pytoolsmith-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 423187a26cb760cf2069a40833d2cf24259d5da822da674409a95bbe7a4bae9a
MD5 e590cf397cf6b57e5aa4719c30f7f879
BLAKE2b-256 fc5a726e43d8a546e5911bbb89b32d8776c6394ef3379a0e2135901a4fad1e5e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page