Function Tools
Purpose
Within the broader Tooling System of the modular tool framework, Function Tools provide a generic mechanism to expose native Go functions as callable tools for agents and LLMs. This subtopic addresses the need for easily wrapping arbitrary Go functions with automatic JSON schema inference for their inputs and outputs, enabling seamless integration with LLM-based agents. By doing so, function tools allow developers to extend agent capabilities by plugging in custom business logic or computations without manually defining schemas or serialization logic.
This approach complements other tool types like artifact loaders or web search tools by focusing on direct function invocation with strongly-typed parameters and results, facilitating structured interactions between agents and native code.
Functionality
Core Features
Automatic JSON Schema Inference: When wrapping a Go function, the system introspects its input and output types using the jsonschema package to automatically generate JSON schemas. These schemas define the expected parameters and response structures for the tool, which are then embedded into the LLM function declaration. This eliminates the need for manual schema authoring.
Generic Function Wrapping: The tool accepts any Go function matching the signature
func(tool.Context, TArgs) (TResults, error), where TArgs andTResultsare generic types. This design enables flexible wrapping of functions with arbitrary structured input and output types.Integration with LLM Function Calling: The function tool packs the function declaration (name, description, parameter schema) into the LLM request so that the LLM can invoke it via function calls. When the LLM issues a function call, the tool deserializes the JSON arguments, calls the underlying Go function, and serializes the results back into JSON for the LLM.
Error Handling and Output Normalization: The tool handles error returns from the wrapped function and converts output values into the expected map[string]any format. It includes logic to wrap primitive or non-object results into a
{"result": value}structure to meet function call response requirements.Optional Custom Schemas: Developers can override the inferred input or output schemas by supplying explicit JSON schemas during tool construction, allowing for validation constraints like enums or descriptions.
Key Workflows
Tool Creation:
Using functiontool.New(), a developer provides a tool name, description, and a handler function. The system automatically infers input/output JSON schemas unless overridden.LLM Request Preparation:
When the agent prepares an LLM request, it calls ProcessRequest() on the function tool, which embeds the function declaration (including schemas) into the request config. This enables the LLM to know how to call the function.Function Call Execution:
When the LLM triggers a function call, the agent invokes Run() on the function tool, passing the JSON arguments. The tool deserializes the arguments into the typed input, executes the Go handler, and serializes the results back into JSON.Result Return:
The serialized output is returned to the LLM, which can incorporate the function call's results in subsequent reasoning or responses.
This flow enables agents to dynamically extend their behavior by calling native Go functions exposed as tools, without manual schema management or serialization boilerplate.
Example Snippet
type SumArgs struct {
A int `json:"a"`
B int `json:"b"`
}
type SumResult struct {
Sum int `json:"sum"`
}
handler := func(ctx tool.Context, input SumArgs) (SumResult, error) {
return SumResult{Sum: input.A + input.B}, nil
}
sumTool, err := functiontool.New(functiontool.Config{
Name: "sum",
Description: "sums two integers",
}, handler)
This example wraps a simple sum function into a tool with automatic input/output schema generation.
Integration
Function Tools integrate tightly with the parent Tooling System by implementing the common tool.Tool interface. They can be added to an agent's toolset alongside other tool types like artifact loaders, search tools, or MCP toolsets, allowing agents to call them uniformly.
Within the LLM Integration and Agents topic, function tools enable LLMs to invoke native Go functions through LLM function calls, bridging the gap between language model reasoning and structured programmatic behavior.
Function tools complement other subtopics such as:
Artifact Loading Tool: Whereas artifact loaders primarily handle file or blob data, function tools focus on arbitrary logic encapsulated in Go functions.
Agent Tools: Function tools provide atomic function calls, while agent tools may wrap entire sub-agents for delegation.
Instruction Template Processing: Function tools can be referenced by name within instruction templates to influence prompt construction and function call triggering.
Function Tools also support long-running operations by marking tools with IsLongRunning in the config, informing agents and LLMs about the nature of the function execution.
Diagram
sequenceDiagram
participant Agent
participant LLM
participant FunctionTool
participant GoFunction
Agent->>LLM: Prepare LLMRequest with FunctionTool declarations
LLM->>Agent: Generate content, may issue FunctionCall
Agent->>FunctionTool: Run with JSON arguments from FunctionCall
FunctionTool->>GoFunction: Deserialize args and invoke Go function
GoFunction-->>FunctionTool: Return result or error
FunctionTool-->>Agent: Serialize and return result map
Agent->>LLM: Provide function call result
This sequence illustrates the core interaction flow where the agent prepares the LLM request embedding function tool declarations, the LLM generates content including a function call, and the function tool executes the wrapped Go function returning results back to the agent and LLM.