Tools
Define and use tools within Rigging pipelines.
Tools in Rigging allow language models to interact with external systems, execute code, or perform well-defined tasks during generation. Rigging v3 introduces a unified tool system, making it easier to define tools and control how they interact with different language models.
For most uses, you can just build any function with type hints, and pass that into a pipeline:
Defining Tools
Rigging uses function signatures (type hints and docstrings) to automatically generate the necessary schema and description for the language model. If you’d like to make any modifications to your tool’s name, description, or schema, you can use the @tool
decorator and pass that into pipelines.
Using @tool
for Functions
Decorate any regular Python function (including static methods) with @rigging.tool.tool
to make it usable by the Rigging framework.
- Type hints are crucial for defining the parameters the model needs to provide.
- Use
typing.Annotated
to provide descriptions for parameters where needed. - The function’s docstring is used as the tool’s description for the model.
Using @tool_method
for Class Methods
If your tool logic resides within a class and needs access to instance state (self
), use the @rigging.tool.tool_method
decorator instead.
@tool_method
correctly handles the self
argument, ensuring it’s not included in the schema presented to the language model. Use @tool
for static methods if they don’t require self
.
Underlying Mechanism
Both decorators use Tool.from_callable()
internally to wrap your function/method into a Tool
object. This object holds the function, its generated schema, name, and description.
Using Tools in Pipelines
To make tools available during generation, pass them to the ChatPipeline.using()
method.
Tool Invocation Modes (mode
)
The mode
parameter in .using()
controls how Rigging interacts with the language model for tool calls:
auto
(Default): Rigging checks if the model provider supports API-level function calling (like OpenAI, Anthropic, Google). If yes, it uses that native, efficient mechanism. If not, it falls back toxml
.api
: Forces the use of the provider’s function calling API. Will fail if the provider doesn’t support it.xml
: Rigging injects instructions and an XML schema into the prompt, telling the model how to format its output to request a tool call using specific XML tags. Rigging parses this XML.json-in-xml
: Similar toxml
, but the model is instructed to place a JSON object containing the arguments within the XML tags.
Generally, auto
is recommended as it leverages the most efficient method available.
Controlling Recursion (max_depth
)
The max_depth
parameter limits how many levels deep tool calls can go. If a tool itself triggers another prompt that uses tools, this prevents infinite loops.
MCP Integration (Model Context Protocol)
The Model Context Protocol (MCP) is an open standard for language models to interact with external tools and services. Rigging provides a client to connect to MCP-compliant servers.
Use the rigging.tool.mcp
function, specifying the transport method (stdio
or sse
) and the connection parameters. It returns an async context manager.
Using stdio
(Standard Input/Output)
Connect to an MCP server launched as a local process that communicates over standard input/output.
Using sse
(Server-Sent Events)
Connect to an MCP server exposed via an HTTP endpoint using Server-Sent Events.
The mcp
context manager handles the connection, tool discovery, and communication with the MCP server. Inside the async with
block, mcp_client.tools
provides the list of discovered Tool
objects ready to be used with .using()
.
Robopages
Robopages is a framework for building and hosting tool-enabled “pages” or APIs. Rigging can dynamically fetch the available tools from a running Robopages server and make them available to your language model.
Use the rigging.tool.robopages
function to connect to a Robopages endpoint and retrieve its tools.
This fetches the tool definitions (name, description, parameters) from the Robopages server. When the language model requests one of these tools, Rigging sends the request back to the Robopages server for execution.
Tool Execution Flow
When you call .using()
:
- Rigging prepares the tool definitions based on the selected
mode
. - For
api
mode, the definitions (ApiToolDefinition
) are passed to the model provider’s API. - For
xml
orjson-in-xml
modes, Rigging injects the tool schemas and usage instructions into the system prompt. - During generation, if the model decides to call a tool:
- In
api
mode, the provider returns structured tool call information (ApiToolCall
). - In native modes, Rigging parses the model’s output for the expected XML format (
XmlToolCall
orJsonInXmlToolCall
).
- In
- Rigging validates the arguments provided by the model against the tool’s signature using Pydantic.
- Your original Python function/method (or the relevant MCP/Robopages call) is executed with the validated arguments.
- The return value is formatted into a message (
Message
withrole="tool
for API calls, or a user message containingNativeToolResult
for native calls) and sent back to the model. - The generation process continues until the model produces a final response without tool calls or the
max_depth
is reached.
Error Handling
You can control how errors raised within your tool function are handled using the catch
parameter in @tool
/ @tool_method
:
catch=False
(Default): Errors propagate, potentially failing the pipeline run (unless caught bypipeline.catch()
).catch=True
: Catches any exception, converts it to an error message, and sends that back to the model as the tool result.catch={ValueError, TypeError}
: Catches only specified exception types.
Tool State
Since tools defined with @tool_method
operate on class instances, they can maintain and modify state across multiple calls within a single pipeline execution.
You could also do the same thing by returning a stateful tool function defined in a closure: