Data Format for Fine-Tuning Needle 2: JSONL Structure and Schema Requirements
Needle 2 requires a JSON Lines (JSONL) dataset where each line contains a single JSON object with required fields query, tools, and answers, plus optional reasoning and system fields for improved grounding and system message prepending.
The data format for fine-tuning Needle 2 follows a strict schema designed for LoRA adapter training on tool-calling tasks. According to the cactus-compute/needle source code, the pipeline expects training examples in JSONL format, processed by the load_jsonl function in needle/model/finetune.py to render prompt/target pairs for tokenization.
JSONL File Structure
Needle 2 training data uses JSON Lines format (.jsonl), meaning the file contains one JSON object per line with no trailing commas between records. This structure allows the fine-tuning pipeline to stream large datasets efficiently without loading the entire file into memory.
The parser in needle/model/finetune.py reads each line individually, validates the schema, and performs deduplication before feeding examples into the LoRA training loop.
Required Fields
Every training example must include three core fields:
-
query(string): The user request or passage that the model will process. This represents the input context that should trigger specific tool calls. -
tools(array): A catalogue of tool objects available for the turn. Each object defines the tool name and JSON schema for its parameters. This field can be omitted only if the model already has access to the tools through other means. -
answers(array): An array of call objects representing the exact tool calls the model should emit for the given query. Each object containsnameandargumentskeys mapping to the intended function call.
Optional Fields
Two additional fields improve model quality:
-
reasoning(string): A short explanation showing how each argument is derived from a specific span in the query. Including this field teaches the model to ground its arguments to source text, reducing hallucinations. -
system(string): A system message that will be prepended to the prompt, equivalent to passingNeedle(system=...)in the Python API.
Field Specifications and Schema
The answers array must contain only arguments that actually appear in the query text. According to the fine-tuning documentation in doc/finetuning.md, missing optional fields should be omitted entirely rather than filled with placeholder values.
Tool definitions in the tools array follow the JSON Schema format with type, properties, and required keys. The model uses these schemas to validate argument structure during inference.
Best Practices for Training Data
The documentation in doc/finetuning.md specifies several critical rules for dataset curation:
Include off-topic examples. Approximately one in eight examples (≈12.5%) should set "answers": [] to teach the model when not to call any tools. This prevents over-triggering on irrelevant queries.
Provide reasoning traces. While optional, the reasoning field significantly improves argument grounding. The training pipeline in needle/model/finetune.py uses these traces to align parameter values with their source spans in the query text.
Validate argument coverage. Ensure every parameter in answers appears verbatim in the query string. The fine-tuning renderer checks this consistency during prompt generation.
Fine-Tuning Pipeline Implementation
The actual training logic resides in needle/model/finetune.py, which implements the complete LoRA fine-tuning workflow:
-
Loading: The
load_jsonlfunction streams the dataset line-by-line, parsing each JSON object and filtering malformed entries. -
Rendering: Examples are converted to prompt/target pairs using the tokenizer defined in
needle/model/tokenizer.py. -
Augmentation: The pipeline performs dataset augmentation and deduplication before training.
-
Training: The
finetune_localfunction handles the LoRA training loop, saving adapter weights for later merging with the base model.
Creating Your Training Dataset
Generate a valid JSONL file using Python's json module:
import json
example = {
"query": "Bantilan, N. (2018). Themis. Journal of Technology in Human Services, 36(1).",
"tools": [
{
"name": "extract_citation_data",
"parameters": {
"type": "object",
"properties": {
"authors": {"type": "string"},
"title": {"type": "string"},
"publisher": {"type": "string"}
},
"required": ["authors", "title"]
}
}
],
"answers": [
{
"name": "extract_citation_data",
"arguments": {
"authors": "Bantilan, N.",
"title": "Themis",
"publisher": "Journal of Technology in Human Services, 36(1)."
}
}
],
"reasoning": "authors precede the year; title follows the year; publisher is the journal segment"
}
with open("data.jsonl", "w") as f:
f.write(json.dumps(example) + "\n")
Running Fine-Tuning
Execute the LoRA training using the Needle CLI:
# Train LoRA adapter on custom dataset
needle finetune data.jsonl --epochs 10 --out adapter.pkl
# Merge adapter with base checkpoint to create deployable model
needle build checkpoints/needle2.pkl --lora adapter.pkl --out tuned.cact
The base model checkpoint loading logic in needle/model/run.py handles the initial weight loading before the LoRA adapter is merged during the build process.
Loading Tuned Models
Deploy the fine-tuned model in Python:
import needle
agent = needle.Needle(
tools=[extract_citation_data],
weights="tuned.cact"
)
result = agent.process("Bantilan, N. (2018). Themis...")
Summary
- Needle 2 requires JSON Lines format (
.jsonl) with one JSON object per line, parsed byneedle/model/finetune.py. - Required fields are
query(input text),tools(available functions), andanswers(target calls). - Optional
reasoningfields improve grounding by explaining how arguments map to query spans. - Optional
systemfields prepend system messages to training prompts. - Include approximately 12.5% off-topic examples (empty
answersarrays) to prevent false positives. - Use
needle finetuneto train LoRA adapters, thenneedle buildto merge them into deployable.cactfiles.
Frequently Asked Questions
What file extension should I use for Needle 2 training data?
Use the .jsonl extension for JSON Lines format. The load_jsonl function in needle/model/finetune.py expects one valid JSON object per line with newline delimiters, not a JSON array containing multiple objects.
Does the tools field need to be repeated in every example?
No. If the model already knows the available tools through configuration, you can omit the tools field from individual examples. However, including it ensures the training context matches inference conditions exactly.
How should I handle optional parameters that are missing from the query?
Omit missing optional parameters from the arguments object entirely. According to doc/finetuning.md, you should never use placeholder values like "null" or "N/A" for missing optional fields. The model learns to exclude these keys when the information is absent from the query.
Can I mix multiple tool types in a single training file?
Yes. The JSONL format supports heterogeneous training examples. Each line can reference different tools in its tools array and answers array, allowing you to train a single LoRA adapter on diverse tool-calling scenarios.
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 →