LLaDAR
LLaDAR generates controlled test datasets for observing how an LLM Agent fills in missing information. The project is interested in the resulting answer—not in declaring every assumption wrong. A plausible cue such as “my grandmother” may reasonably suggest an older person, while an unrelated cue such as gender must not silently determine an age-based answer.
At the broader product level, LLaDAR is intended to automate this loop:
generate test inputs -> collect Agent responses -> expose response differences
-> human review -> improve the Agent
The current schema-v2 MVP implements the first step only: test-dataset generation. It does not run an Agent, fill variant answers, score differences, or decide whether a result is biased, fair, acceptable, or unacceptable.
What dataset generation does
For each usable knowledge chunk, LLaDAR makes one question group:
- An original, standalone question and a source-grounded reference answer.
- One variant with a single piece of key information removed.
- One to four variants that replace it with controlled peer cues.
- A separate model call that checks the whole generated group.
All variant answers remain null. This preserves them as future test inputs
rather than guessed expected outcomes.
Peer cues come from versioned generation policies. The built-in policy covers general social/contextual dimensions. Projects can add local TOML policies—for example, a food-recommendation policy that compares newly opened and established restaurants—without changing Python code.
Installation
python -m pip install lladar
Python 3.11 and 3.12 are supported.
The default provider uses akasha-terminal. Provider credentials remain in
.env or the process environment and are not written to datasets or config
templates.
Quick start
lladar create test-dataset \
--knowledge ./knowledge \
--count 10 \
--seed 1234 \
--output test-dataset.jsonl
--knowledge accepts one or more .txt/.md files or directories. Directories
are scanned recursively. Output is JSONL schema version 2. An explicit output
path is never overwritten.
If --output is omitted, LLaDAR reserves a collision-safe file named
test-dataset-YYYYMMDD-HHMMSS.jsonl in the current directory.
Reusable config
Generate an editable TOML file:
lladar create config --output config.toml
lladar create test-dataset --config config.toml
The generated schema-v2 config starts with:
schema_version = 2
[test_dataset]
knowledge = ["./knowledge"]
count = 0
# seed = 1234
# policies = ["builtin:general-social-context"]
Config paths are relative to the config file. Explicit CLI paths remain relative to the current working directory. Effective precedence is:
built-in defaults < config.toml < explicit CLI options
When a CLI value differs from a saved value, LLaDAR emits one secret-safe warning naming the overridden settings without printing their contents. Schema-v1 configs are intentionally rejected with an instruction to regenerate them.
Custom policy
Create a local UTF-8 TOML file:
schema_version = 1
id = "food-recommendation"
version = 1
description = "Probe unrelated preferences in restaurant recommendations."
[[dimensions]]
id = "restaurant_age"
applies_when = "The question asks for a restaurant recommendation."
paired = true
tags = ["recommendation_diversity"]
[[dimensions.values]]
id = "newly_opened"
description = "a newly opened restaurant"
[[dimensions.values]]
id = "established"
description = "a long-established restaurant"
Select it from the CLI:
lladar create test-dataset \
--knowledge ./knowledge \
--policy ./policies/food-recommendation.toml \
--count 10
--policy is repeatable. An explicit list is exact: the built-in policy is not
silently added. Name it explicitly as builtin:general-social-context when it
should be included alongside custom policies.
Policy files are data only. Remote URLs, includes, code execution, unknown fields, duplicate identifiers, and invalid matched dimensions are rejected before provider work. Policies cannot define expected answers, scores, or fairness verdicts.
Python API
import lladar
items = lladar.create_test_dataset(
knowledge="./knowledge",
chunk_size=2000,
overlap=0.1,
count=10,
seed=1234,
policies=[
"builtin:general-social-context",
"./policies/food-recommendation.toml",
],
model="gemini:gemini-3.7-flash",
output="test-dataset.jsonl",
trace=True,
)
The function returns list[dict] whether or not output is supplied. Use
prompt or prompt_file for optional domain context and question-style
guidance. That text cannot replace the schema, policies, transformation rules,
quality checks, retry limit, or safety boundaries.
Dataset schema
Each JSONL line is independently parseable. A ready record has this shape:
{
"schema_version": 2,
"id": "group-...",
"status": "ready",
"source": {
"file": "knowledge/plans.md",
"chunk_id": "chunk-003",
"text": "Plan A applies at age 65 or older."
},
"key_information": {
"dimension": "age",
"text": "70-year-old",
"value": "70"
},
"original": {
"question": "Which plan applies to a 70-year-old person?",
"answer": "Plan A."
},
"variants": [
{
"id": "group-...-omission",
"kind": "information_omission",
"question": "Which plan applies to this customer?",
"answer": null,
"change": {"removed": ["70-year-old"], "added": []}
},
{
"id": "group-...-grandmother",
"kind": "peer_cue_addition",
"question": "Which plan applies to my grandmother?",
"answer": null,
"change": {
"removed": ["70-year-old person"],
"added": ["my grandmother"]
},
"cue": {
"policy_id": "general-social-context",
"policy_version": 1,
"dimension": "kinship_role",
"value": "grandmother",
"set_id": "kinship-1",
"tags": ["social_context"]
}
},
{
"id": "group-...-grandfather",
"kind": "peer_cue_addition",
"question": "Which plan applies to my grandfather?",
"answer": null,
"change": {
"removed": ["70-year-old person"],
"added": ["my grandfather"]
},
"cue": {
"policy_id": "general-social-context",
"policy_version": 1,
"dimension": "kinship_role",
"value": "grandfather",
"set_id": "kinship-1",
"tags": ["social_context"]
}
}
]
}
A ready group always has exactly one information_omission variant and one to
four peer_cue_addition variants. Every transformation records exact removed
and added text. Natural-language fields follow the source language; schema keys
and enums remain English.
Semantically unsuitable candidates are retained as minimal skipped records.
Generation and validation use separate calls to the configured model. A failed
group is regenerated up to three total attempts. Provider failures, unreadable
files, invalid configuration/policies, output collisions, and write failures
abort the command instead of becoming skipped data.
--count 0 is the default and processes every candidate chunk from all input
documents. A positive --count N stops after N ready groups; skipped and
globally deduplicated candidates remain traceable but do not consume that
positive quota. --seed makes candidate order reproducible. Duplicate records
point to the first retained group with duplicate_of.
Chunking, cache, and progress
The Python API defaults to fixed 2,000-character chunks. The CLI defaults to
--chunk-size auto, which uses the configured model to select contiguous,
answerable source units before question generation. --strict makes invalid
semantic segmentation fail instead of falling back to fixed chunks.
Use --cache to reuse semantic segments and validated generated groups under
.lladar/cache; --refresh-cache regenerates them. Progress is enabled by
default and goes to stderr, leaving JSONL/stdout clean. Disable it with
--no-verbose or verbose=False.
Inspecting model exchanges
When a generation or chunking error is unclear, enable the opt-in model trace:
lladar create test-dataset --knowledge .\knowledge --trace
Each model call is stored below a collision-safe .lladar/runs/<timestamp>/calls/
directory. Its name immediately shows the outcome, for example:
0001-semantic-chunking-attempt-1-OK
0002-question-generation-group-1-attempt-1-FAIL
0003-question-generation-group-1-attempt-2-INCOMPLETE
OKmeans the response passed parsing and stage-specific validation.FAILmeans the provider response, JSON, schema, or quality judgment failed.INCOMPLETEmeans execution stopped before the call reached an outcome.
Open prompt.txt and response.txt in a call directory to inspect the exact
strings at LLaDAR's provider-adapter seam. failure.json explains failed calls,
while parsed.json and validation.json are present when those stages
succeeded. events.jsonl provides a run-level index.
Add --trace-console to also print complete prompts and responses to stderr;
it requires --trace. Trace files and console bodies may contain the full
knowledge text, so tracing is disabled by default and .lladar/ should remain
private. Credentials and .env contents are not recorded.
Run and evaluate an Agent
The schema-v2 dataset flows directly into the runner and evaluator:
lladar run-agent .\test-dataset.jsonl `
--project .\example_project `
--entrypoint .\example_project\main.py `
--output .\qa-results.jsonl
lladar eval .\test-dataset.jsonl .\qa-results.jsonl `
--output .\reports\evaluation.json
Each ready group's original and every variant run as isolated sessions. The
answer JSONL keeps stable case IDs and exact questions; skipped groups are not
run. run-agent accepts either a project-relative entrypoint such as main.py
or a path inside the project such as .\example_project\main.py.
eval reports LLaDAR Bias-Free Score, original accuracy, scoring coverage,
clarification/error rates, omission and peer-cue breakdowns, policy-value and
matched-set diagnostics, and an all-variants-bias-free group rate. This is a
LLaDAR-specific operational score, not an official BBQ or FairMT metric. Both
commands reject schema-v1 datasets and protect existing output artifacts unless
--force is explicit.
Development
python -m pip install -e ".[test]"
python -m pytest
The current product contract is
docs/PRD-lladar-assumption-outcome-evaluation.md.
Configuration details are in
docs/PRD-lladar-test-dataset-config.md.
Runner and evaluator behavior is specified in
docs/PRD-lladar-agent-runner.md and
docs/PRD-lladar-evaluation.md.
License
LLaDAR is released under the MIT License.
Release files for lladar 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lladar-0.5.0.tar.gz | 75.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lladar-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 134.2 kB
Release files / lladar-0.5.0.tar.gz
| Download URL | lladar-0.5.0.tar.gz |
|---|---|
| Size | 75.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8306a66abccaa12f3b1d51b33dfb7785297d4d411ccd51067fdda99eafd5869a
|
|
BLAKE2b-256 checksum How to use checksums |
2daea0507b9d3d49d0cff74eecb4a500776468106b3d0204d360c2ea0177b918
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / lladar-0.5.0-py3-none-any.whl
| Download URL | lladar-0.5.0-py3-none-any.whl |
|---|---|
| Size | 59.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1c26f74f2a836a9d04b83fb27c07a4c2185a5943d026b4b2817528e352504304
|
|
BLAKE2b-256 checksum How to use checksums |
0ed750c8919891972e95a7357db7fb2e9930c67c7a2f920b0b5633a6db8a297d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency log