# Needle extract() Function: One-Shot Structured Extraction Guide

> Master the Needle extract() function for one-shot structured extraction. Effortlessly parse data using Pydantic models or dict schemas with this stateless, high-performance tool.

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

---

**The `needle.extract()` function provides a stateless shortcut for performing single-step structured extraction by automatically wrapping a Pydantic model or dictionary schema as a temporary tool, executing it through the native C engine, and returning parsed results without manual agent instantiation.**

Needle is an open-source library that simplifies structured data extraction from unstructured text using local language models. The `extract()` function offers a convenient one-shot interface that eliminates the need to manually instantiate and configure a `Needle` agent for simple extraction tasks. This approach leverages the library's native C bindings to perform fast, isolated extractions based on user-supplied schemas.

## How extract() Works Internally

The `extract()` function in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) implements a four-stage pipeline that transforms raw text into structured data through temporary agent instantiation.

### Wrapping the Schema as a Temporary Tool

At lines 57-62 of [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py), the function creates a temporary `Needle` instance and registers the supplied schema as the agent's sole available tool. This schema can be either a **Pydantic model** or a plain Python dictionary representing an OpenAI-compatible function definition. By wrapping the schema as the only tool, the function constrains the model to output exactly the structured format specified.

### Executing Through the Native Engine

The temporary agent calls `complete()` (lines 103-111 in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py)), which interfaces directly with Needle's native C library. This low-level binding handles the inference execution and returns a JSON envelope containing potential function calls. The engine processes the user text through the specified **shared engine** without requiring explicit agent management code.

### Parsing Function Calls

At lines 163-167 in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py), the function extracts the first item from the `function_calls` array in the JSON response. The `arguments` field of this call contains the extracted structured data as a JSON object. This design assumes the schema acts as a function signature, with the model's output being a "function call" containing the extracted parameters.

### Schema Instantiation

The final step (lines 166-167) determines the return type based on the input schema type. If the schema is a Pydantic model class, the function feeds the extracted arguments into the model constructor and returns a validated instance. If the schema is a plain dictionary, it returns the arguments as a standard Python `dict`.

## Schema Conversion and Tool Building

Behind the scenes, `extract()` relies on the tool builder in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py) to convert Python types into JSON schemas that the underlying engine understands.

### Pydantic Model Serialization

When provided a Pydantic model, the function calls `pydantic_schema()` (lines 49-56 in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py)). This method extracts the model's JSON schema using Pydantic's native serialization, ensuring that field types, constraints, and validation rules are preserved in the OpenAI-compatible tool definition.

### Callable Inspection

For regular Python functions or callables, `build_schema()` (lines 110-140 in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py)) introspects the function signature, type hints, and docstring to generate an appropriate JSON schema. This allows `extract()` to work with dynamically defined structures without requiring formal Pydantic definitions.

## Practical Code Examples

### Extracting into a Pydantic Model

```python
import pydantic
from needle import extract

class Contact(pydantic.BaseModel):
    name: str
    email: str

text = "John Doe can be reached at john@doe.com"
contact = extract(text, Contact)          # → Contact(name='John Doe', email='john@doe.com')

print(contact)

```

### Extracting into a Plain Dictionary

```python
from needle import extract

schema = {
    "name": "person",
    "parameters": {
        "type": "object",
        "properties": {
            "first_name": {"type": "string"},
            "age": {"type": "integer"}
        },
        "required": ["first_name"]
    }
}

result = extract("Alice is 30 years old", schema)   # → {'first_name': 'Alice', 'age': 30}

print(result)

```

### Using a Custom System Prompt

```python
from needle import extract

prompt = "You are a friendly assistant that extracts contact info."
contact = extract("Reach me at jane@example.com", Contact, system=prompt)

```

## Isolation and State Management

Because `extract()` constructs a fresh `Needle` instance on each invocation, it **does not affect existing agents** that may have been created earlier in your application. This isolation is verified by the test `test_extract_keeps_agent_tools` in [`tests/test_inference.py`](https://github.com/cactus-compute/needle/blob/main/tests/test_inference.py) (lines 71-90), which confirms that calling `extract()` leaves pre-existing agent tool configurations intact.

The one-shot nature means there is no persistent state between calls—each extraction is completely independent, making the function thread-safe and suitable for stateless serverless environments where you need deterministic, side-effect-free structured extraction.

## Summary

- **`extract()` creates temporary agents**: Each call instantiates a fresh `Needle` instance with your schema as the only tool, ensuring isolation from other agents.
- **Native C engine integration**: The function routes text through `complete()` to Needle's native C library for fast inference, then parses the `function_calls` array in the JSON response.
- **Flexible schema support**: Accepts both Pydantic models (validated instances) and plain dictionaries (raw key-value extraction) through automatic schema conversion in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py).
- **Stateless operation**: No side effects on existing agent instances, making it safe for concurrent or repeated use without manual resource management.

## Frequently Asked Questions

### What is the difference between `extract()` and a manual `Needle` agent?

`extract()` is a convenience wrapper that creates a temporary, single-purpose agent for one-shot extractions. A manual `Needle` agent persists between calls, maintains conversation state, and supports multiple tools—making it suitable for complex multi-turn interactions, while `extract()` is optimized for simple, stateless structured data extraction.

### Can `extract()` handle both Pydantic models and plain dictionaries?

Yes. When you pass a Pydantic model class, `extract()` returns a validated instance of that model via `pydantic_schema()` in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py). When you pass a plain dictionary schema, it returns a standard Python dictionary. Both paths use the same underlying engine but differ in how the output is instantiated.

### Does `extract()` modify existing `Needle` agent instances?

No. According to the source code in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) and verified by [`tests/test_inference.py`](https://github.com/cactus-compute/needle/blob/main/tests/test_inference.py) (lines 71-90), `extract()` constructs a completely new `Needle` instance internally. This isolation ensures that existing agents with their own tool configurations remain unaffected by extraction operations.

### How does `extract()` convert Python types to JSON schemas?

The function delegates to `build_schema()` and `pydantic_schema()` in [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py). For Pydantic models, it serializes the model's JSON schema directly (lines 49-56). For regular callables, it inspects function signatures, type hints, and docstrings to generate OpenAI-compatible JSON schemas (lines 110-140), allowing the native C engine to enforce the structure during inference.