How Needle Tool Retrieval Works When More Than Five Tools Are Declared

Needle retrieves tools dynamically by sending only the first five tool schemas in the initial LLM request, then fetching additional tools on-demand when the model specifically requests them, ensuring compliance with OpenAI's five-tool limit while supporting unlimited tool declarations.

The cactus-compute/needle framework provides Python developers with a lightweight agent system that supports OpenAI-style function calling. When your application registers more than five tools, Needle implements an intelligent tool retrieval process that keeps individual LLM requests within API constraints while maintaining full access to your complete tool registry.

Tool Registration and Schema Generation

Every function marked with the @tool decorator becomes available to the language model through a structured JSON schema. In needle/agent/tools.py (lines 68‑71), the decorator attaches metadata to the function object via fn._needle_tool, storing the schema generated by the build_schema function. This schema includes the function name, description, and parameters required for OpenAI function-calling compliance.

All decorated functions are automatically collected into a global registry, implemented as a simple list within the needle.agent package. This registry maintains references to every tool your application declares, regardless of quantity.

The Five-Tool Limit and Initial Request Strategy

The underlying LLM API imposes a hard limit of five tools per request. To respect this constraint, Needle's execution logic in needle/agent/__init__.py includes only the first five tool schemas from the registry when making the initial model call. This batching strategy prevents request errors while allowing your application to declare an unlimited number of tools in the global registry.

If the model determines it needs a tool from outside this initial batch, the response will indicate a function_call with a name not present in the sent subset. This triggers the retrieval mechanism to locate and supply the missing schema.

Dynamic Tool Retrieval Process

When the model requests a tool not included in the initial five, Needle performs a tool-retrieval step before executing the function call. The framework inspects the global registry to locate the specific tool schema by name. It then constructs a follow-up request containing just that additional tool (or a minimal batch that includes it while keeping the total count ≤ 5).

This creates an iterative calling pattern: the model may make several back-and-forth requests, each time receiving only the tool schemas it needs to complete the task. The process continues until the required tool is available for execution, ensuring that the five-tool ceiling is never exceeded in any single API call.

Practical Implementation Example

The following code demonstrates how tools are declared, registered, and retrieved dynamically:


# 1. Declare a tool (the decorator builds its schema)

from needle.agent.tools import tool, Field

@tool
def translate(text: str, target_lang: str = Field(enum=["es", "fr", "de"])) -> str:
    """Translate *text* into the target language."""
    ...

# 2. Internally, the decorator stores the schema:

#    translate._needle_tool == {

#        "name": "translate",

#        "description": "...",

#        "parameters": { ... }

#    }

# 3. When invoking the agent:

from needle.agent import run

# The agent sends only the first five tool schemas:

response = run(prompt="Please translate this to Spanish.", tools=first_five_tools)

# 4. If the model asks for a sixth tool, Needle fetches it:

#    (pseudo-code – the real logic lives in needle/agent/__init__.py)

if response.function_call not in first_five:
    extra_tool = registry.lookup(response.function_call)
    response = run(prompt=prompt, tools=[extra_tool])

Key Source Files

Understanding the tool retrieval mechanism requires familiarity with these core files:

  • needle/agent/tools.py – Defines the Field class, build_schema function, and the @tool decorator that creates JSON schemas for function calling.
  • needle/agent/__init__.py – Implements the global tool registry and contains the logic that limits requests to five tools while handling dynamic retrieval of additional tools.
  • needle/cli.py – Serves as the entry point that invokes the agent and passes the appropriate tool lists to the LLM.
  • README.md and doc/apis.md – Document the tool-calling capability and explicitly reference the five-tool limit.

Summary

  • Tool registration uses the @tool decorator in needle/agent/tools.py to attach JSON schemas to functions via fn._needle_tool.
  • Initial requests include only the first five tools from the global registry to comply with OpenAI API limits.
  • Dynamic retrieval occurs when the model requests a tool outside the initial batch, triggering a follow-up request with the specific missing schema.
  • Iterative calling allows unlimited tool usage across multiple requests while maintaining the five-tool ceiling per individual call.
  • The registry and retrieval logic reside primarily in needle/agent/__init__.py.

Frequently Asked Questions

Why does Needle limit requests to five tools?

The five-tool limit aligns with the OpenAI function-calling API specification, which restricts each request to a maximum of five function definitions. Needle enforces this ceiling in needle/agent/__init__.py to prevent API errors while allowing your application to declare any number of tools in the global registry.

What happens if the model requests a tool not in the registry?

If the model returns a function_call with a name that does not exist in the global registry, Needle cannot execute the request. The framework relies on the registry lookup in needle/agent/__init__.py to locate tool schemas; missing entries will cause the retrieval step to fail until the tool is properly registered with the @tool decorator.

Where is the tool registry stored in Needle?

The tool registry is implemented as a simple list within the needle.agent package, specifically managed in needle/agent/__init__.py. This global collection accumulates every function decorated with @tool from needle/agent/tools.py, making all schemas available for dynamic retrieval during iterative model calls.

Can I modify the five-tool limit in the source code?

While the five-tool limit is hardcoded to match OpenAI's API constraints, you could theoretically adjust the batching logic in needle/agent/__init__.py. However, increasing the limit beyond five tools per request would cause the underlying LLM provider to return an error, as this restriction is enforced at the API level rather than within Needle itself.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →