How to Define Advanced Tool Descriptions with Google-Style Args in Docstrings
Use Google-style Args: sections in function docstrings to automatically populate JSON Schema descriptions for tools decorated with @tool in the Needle framework.
The needle framework transforms Python functions into discoverable agent tools by generating JSON schemas from type annotations and docstrings. By following Google-style conventions, you can attach rich, user-friendly descriptions to every parameter without writing additional boilerplate. This article explains how the schema generation works, where to find the core implementation, and how to combine docstring descriptions with Pydantic-style Field constraints for maximum expressiveness.
How Docstring Parsing Works in Needle
The automatic schema generation relies on two key functions in needle/agent/tools.py.
The _parse_doc Helper
The _parse_doc function (lines 94–107) scans a function's docstring and extracts two pieces of information:
- The free-form description (everything before the
Args:section) - A mapping of argument names to their descriptions from the Google-style block
It recognizes multiple section headers: Args:, Arguments:, Parameters:, or Params:.
The build_schema Integration
During schema construction (lines 116–125), build_schema merges these extracted descriptions into the final JSON schema:
schema["description"] = arg_docs[name] # Merges docstring description into parameter
This happens automatically when you apply the @tool decorator—the parsed descriptions are attached to each parameter's schema without manual intervention.
Writing Effective Google-Style Args Sections
A properly formatted docstring follows this pattern:
"""
Brief description of what the function does.
Args:
param_name: Description of the parameter.
Can span multiple lines with consistent indentation.
another_param: Second parameter description.
"""
The colon after each parameter name is optional but conventional. Indentation must be consistent for multi-line descriptions.
Code Examples
Basic Tool with Argument Descriptions
from needle.agent.tools import tool
@tool
def echo(message: str, repeat: int = 1) -> str:
"""
Echoes a message a number of times.
Args:
message: The text to be echoed.
repeat: How many times to repeat the message. Defaults to 1.
"""
return " ".join([message] * repeat)
The generated schema automatically includes:
"description": "The text to be echoed."formessage"description": "How many times to repeat the message. Defaults to 1."forrepeat- The default value
1is captured from the function signature
Advanced Tool with Field Constraints and Docstrings
from needle.agent.tools import tool, Field
@tool
def resize(
width: int = Field(ge=1, description="Target width in pixels."),
height: int = Field(ge=1, description="Target height in pixels."),
keep_aspect: bool = Field(default=True, description="Preserve aspect ratio.")
) -> None:
"""
Resizes an image to the specified dimensions.
Args:
width: Desired image width.
height: Desired image height.
keep_aspect: If True, adjusts the other dimension to maintain the original aspect ratio.
"""
# implementation omitted
This pattern combines two description layers:
| Source | Purpose |
|---|---|
Field(description=...) |
Machine-readable schema annotation with validation rules (ge=1) |
Docstring Args: section |
Human-readable explanation consumed by agent systems |
Both descriptions are merged into the final schema, with Field metadata providing structural constraints and docstring text offering narrative context.
Inspecting the Generated Schema
Every @tool-decorated function stores its schema in the _needle_tool attribute:
print(echo._needle_tool)
Expected output:
{
"name": "echo",
"parameters": {
"type": "object",
"properties": {
"message": {"type": "string", "description": "The text to be echoed."},
"repeat": {"type": "integer", "description": "How many times to repeat the message. Defaults to 1.", "default": 1}
},
"required": ["message"]
},
"description": "Echoes a message a number of times."
}
Source File Reference
The following files in the cactus-compute/needle repository implement and expose this functionality:
needle/agent/tools.py— Core utilities for parsing Google-style docstrings, mapping Python types to JSON schema, and attaching schemas via@toolneedle/agent/__init__.py— Public export of thetooldecorator forfrom needle.agent import toolneedle/cli.py— CLI tool registration and discovery demonstrating real-world usagetests/test_tools.py— Unit tests verifying schema generation from docstrings
Summary
- Google-style
Args:sections in docstrings automatically populate parameter descriptions in generated JSON schemas - The
_parse_docfunction intools.pyextracts these descriptions andbuild_schemamerges them into the final schema - Combine
Fieldobjects with docstrings to layer validation constraints on top of human-readable descriptions - Access any tool's schema via the
_needle_toolattribute for debugging or inspection - No extra code is required—the
@tooldecorator handles all extraction and attachment transparently
Frequently Asked Questions
What section headers does Needle recognize for argument documentation?
Needle accepts Args:, Arguments:, Parameters:, or Params: as valid section headers. All are treated identically by the _parse_doc parser in needle/agent/tools.py.
Can I use both Field descriptions and docstring Args for the same parameter?
Yes. Both descriptions are preserved and merged into the final schema. The Field description typically carries validation metadata, while the docstring description provides expanded human-readable context. Agent systems may use either or both depending on their needs.
Does the docstring parser handle type annotations in the Args section?
No. Needle extracts type information from Python's native type hints in the function signature, not from docstring text. The Args: section should contain only parameter names and descriptions—types are inferred from annotations like message: str.
Where does the function-level description come from?
The overall tool description comes from the text in the docstring before the Args: section. Everything above the first recognized argument header becomes the tool's top-level description in the generated schema.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →