Needle extract() Function: One-Shot Structured Extraction Guide
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 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, 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), 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, 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 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). 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) 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
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
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
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 (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 freshNeedleinstance 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 thefunction_callsarray 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. - 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. 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 and verified by 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. 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.
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 →