# How to Define Advanced Tool Descriptions with Google-Style Args in Docstrings

> Learn to define advanced tool descriptions using Google-style Args in docstrings with the Needle framework. Automatically populate JSON Schema descriptions for your tools.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: how-to-guide
- Published: 2026-08-14

---

**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`](https://github.com/cactus-compute/needle/blob/main/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:

1. The free-form description (everything before the `Args:` section)
2. 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:

```python
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:

```python
"""
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

```python
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."` for `message`
- `"description": "How many times to repeat the message. Defaults to 1."` for `repeat`
- The default value `1` is captured from the function signature

### Advanced Tool with Field Constraints and Docstrings

```python
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:

```python
print(echo._needle_tool)

```

Expected output:

```json
{
  "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`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py)** — Core utilities for parsing Google-style docstrings, mapping Python types to JSON schema, and attaching schemas via `@tool`
- **[`needle/agent/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/__init__.py)** — Public export of the `tool` decorator for `from needle.agent import tool`
- **[`needle/cli.py`](https://github.com/cactus-compute/needle/blob/main/needle/cli.py)** — CLI tool registration and discovery demonstrating real-world usage
- **[`tests/test_tools.py`](https://github.com/cactus-compute/needle/blob/main/tests/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_doc`** function in [`tools.py`](https://github.com/cactus-compute/needle/blob/main/tools.py) extracts these descriptions and **`build_schema`** merges them into the final schema
- Combine **`Field` objects** with docstrings to layer validation constraints on top of human-readable descriptions
- Access any tool's schema via the **`_needle_tool`** attribute for debugging or inspection
- No extra code is required—the `@tool` decorator 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`](https://github.com/cactus-compute/needle/blob/main/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.