# Data Format for Fine-Tuning Needle 2: JSONL Structure and Schema Requirements

> Learn the JSONL data format for fine-tuning Needle 2. Understand required fields like query, tools, and answers, plus optional reasoning and system fields for optimal results.

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

---

**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`](https://github.com/cactus-compute/needle/blob/main/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`](https://github.com/cactus-compute/needle/blob/main/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 contains `name` and `arguments` keys 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 passing `Needle(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`](https://github.com/cactus-compute/needle/blob/main/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`](https://github.com/cactus-compute/needle/blob/main/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`](https://github.com/cactus-compute/needle/blob/main/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`](https://github.com/cactus-compute/needle/blob/main/needle/model/finetune.py), which implements the complete LoRA fine-tuning workflow:

1. **Loading**: The `load_jsonl` function streams the dataset line-by-line, parsing each JSON object and filtering malformed entries.

2. **Rendering**: Examples are converted to prompt/target pairs using the tokenizer defined in [`needle/model/tokenizer.py`](https://github.com/cactus-compute/needle/blob/main/needle/model/tokenizer.py).

3. **Augmentation**: The pipeline performs dataset augmentation and deduplication before training.

4. **Training**: The `finetune_local` function 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:

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

```bash

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

```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 by [`needle/model/finetune.py`](https://github.com/cactus-compute/needle/blob/main/needle/model/finetune.py).
- Required fields are **`query`** (input text), **`tools`** (available functions), and **`answers`** (target calls).
- Optional **`reasoning`** fields improve grounding by explaining how arguments map to query spans.
- Optional **`system`** fields prepend system messages to training prompts.
- Include approximately **12.5% off-topic examples** (empty `answers` arrays) to prevent false positives.
- Use `needle finetune` to train LoRA adapters, then `needle build` to merge them into deployable `.cact` files.

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