[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80080":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":15,"stars7d":15,"stars30d":15,"stars90d":13,"forks30d":13,"starsTrendScore":16,"compositeScore":13,"rankGlobal":10,"rankLanguage":10,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":35,"readmeContent":36,"aiSummary":37,"trendingCount":13,"starSnapshotCount":13,"syncStatus":15,"lastSyncTime":38,"discoverSource":39},80080,"outputguard","ndcorder\u002Foutputguard","ndcorder","Validate, repair, and retry LLM structured outputs. 13 repair strategies for common JSON malformations, JSON Schema validation, and retry-with-feedback prompts.","https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard",null,"Python",59,0,1,2,6,"MIT License",false,"master",true,[22,23,24,25,26,27,28,29,30,31,32,33,34],"ai","anthropic","cli","developer-tools","json","json-repair","json-schema","llm","openai","python","repair","structured-output","validation","2026-06-12 02:03:57","# outputguard\n\n**Stop wrestling with broken LLM structured output.** Validate, repair, and retry — automatically.\n\n[![Python](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpython-3.10+-blue)](https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard)\n[![CI](https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard\u002Factions)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-blue.svg)](LICENSE)\n[![Tests](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Ftests-2,001-brightgreen)](#tested-against-288-real-llm-models)\n\n---\n\n## The Problem\n\nLLMs produce broken structured output constantly. JSON is the common case, but models also return YAML, TOML, Python-style literals when forced JSON is off, markdown fences, comments, trailing commas, `NaN`, truncated objects, and helpful commentary around the data you asked for. Every AI application ends up writing the same brittle parser + `try\u002Fexcept` + regex gauntlet.\n\n## The Solution\n\n```python\nimport outputguard\n\nschema = {\n    \"type\": \"object\",\n    \"properties\": {\n        \"name\": {\"type\": \"string\"},\n        \"age\": {\"type\": \"integer\"}\n    },\n    \"required\": [\"name\", \"age\"]\n}\n\n# Typical LLM output — fenced, trailing comma, single quotes\nllm_output = '''```json\n{'name': 'Alice', 'age': 30,}\n```'''\n\nresult = outputguard.validate_and_repair(llm_output, schema)\nprint(result.valid)              # True\nprint(result.data)               # {'name': 'Alice', 'age': 30}\nprint(result.strategies_applied) # ['strip_fences', 'fix_quotes', 'fix_commas']\n```\n\nFifteen repair strategies, JSON Schema validation, retry prompt generation, and a CLI — now for JSON, YAML, TOML, Python literals, and auto-detected forced-JSON-off output.\n\n## Installation\n\n```bash\npip install outputguard\n```\n\nOr with [uv](https:\u002F\u002Fdocs.astral.sh\u002Fuv\u002F):\n\n```bash\nuv add outputguard\n```\n\n## Documentation\n\nStart with the README for a fast overview, then use the focused guides when you\nneed exact behavior, API signatures, or command examples:\n\n- [API guide](docs\u002Fapi.md) - choose the right function and understand result\n  objects.\n- [Getting started](docs\u002Fgetting-started.md) - first validation, repair, retry,\n  guarded generation, and CLI workflows.\n- [Concepts](docs\u002Fconcepts.md) - the mental model behind parsing, validation,\n  repair, retries, and formats.\n- [Formats guide](docs\u002Fformats.md) - JSON, YAML, TOML, Python literals, `auto`,\n  and `forced-json-off`.\n- [Guarded generation guide](docs\u002Fguarded-generation.md) - wrap an LLM call with\n  validation, repair, retry, and observability.\n- [Batch processing guide](docs\u002Fbatch-processing.md) - validate or repair many\n  outputs in one call or from the CLI.\n- [CLI guide](docs\u002Fcli.md) - commands, flags, examples, and exit codes.\n- [Recipes](docs\u002Frecipes.md) - copy-paste patterns for apps, evals, CI, and\n  privacy-sensitive retries.\n- [Troubleshooting](docs\u002Ftroubleshooting.md) - common symptoms and fixes.\n- [Migration to 2.0](docs\u002Fmigration-2.0.md) - compatibility notes and adoption\n  checklist.\n- [Changelog](CHANGELOG.md) - release notes and 2.0 migration notes.\n\n## What's New in 2.0\n\nOutputGuard 2.0 keeps JSON as the default path, so existing 1.x code continues\nto work without passing new options. The new capabilities are opt-in:\n\n- Format-aware validation and repair with `format=\"json\"`, `\"yaml\"`, `\"toml\"`,\n  `\"python-literal\"`, `\"auto\"`, and `\"forced-json-off\"`.\n- Guarded generation helpers that call your LLM function, validate the response,\n  optionally repair it, and retry with structured feedback.\n- Batch APIs and a `batch` CLI command for evals, logs, and offline audits.\n- More explicit reports and errors for failed guarded-generation runs.\n\n## Choosing the Right API\n\n| Goal | API |\n| --- | --- |\n| Validate and repair one model output | `validate_and_repair()` |\n| Repair without a full validation workflow | `repair()` |\n| Check validity only | `validate()` |\n| Get parsed Python data or raise | `parse()` |\n| Build a validation-aware retry loop | `retry_prompt()` |\n| Wrap an LLM generation function | `guarded_generate()` \u002F `guarded_generate_async()` |\n| Validate many outputs | `validate_batch()` |\n| Repair many outputs | `repair_batch()` |\n\n## Quick Start\n\n### Validate & Repair\n\nThe most common pattern — validate against a schema, auto-repair if broken, get clean data back:\n\n```python\nimport outputguard\n\nresult = outputguard.validate_and_repair(llm_output, schema)\n\nif result.valid:\n    process(result.data)                  # Clean, validated dict\n    if result.repaired:\n        log(result.strategies_applied)    # What was fixed\nelse:\n    handle_errors(result.errors)          # Detailed error paths\n```\n\n### Repair Only\n\nWhen you just need parseable structured output and don't have a schema:\n\n```python\nresult = outputguard.repair(broken_json)\nprint(result.text)                # Clean JSON string by default\nprint(result.strategies_applied)  # ['fix_booleans', 'fix_commas']\n```\n\n### Validate Only\n\nCheck structured output against a schema without attempting repair:\n\n```python\nresult = outputguard.validate(llm_output, schema)\nfor error in result.errors:\n    print(f\"{error.path}: {error.message}\")\n    # $.age: 'thirty' is not of type 'integer'\n```\n\n### Retry Loop\n\nWhen repair is not enough, generate a correction prompt and send it back to the LLM:\n\n```python\nimport outputguard\n\ndef get_structured_output(llm, prompt, schema, max_retries=3):\n    for attempt in range(max_retries + 1):\n        raw = llm.generate(prompt)\n        result = outputguard.validate_and_repair(raw, schema)\n\n        if result.valid:\n            return result.data\n\n        # Generate a targeted correction prompt\n        prompt = outputguard.retry_prompt(raw, schema, result.errors)\n\n    raise RuntimeError(\"Failed to get valid output\")\n```\n\nThe retry prompt tells the LLM exactly what went wrong — which fields are missing, which types are incorrect, and what the schema expects. Works with any LLM provider. By default it includes the previous model output under `Original output:`; pass `include_message_history=False` when you want retry prompts without that message history.\n\n### Guarded Generation\n\nFor production retry loops, use `guarded_generate()` to wrap any LLM client without adding provider dependencies:\n\n```python\nimport outputguard\n\nresult = outputguard.guarded_generate(\n    prompt=\"Return a user object as JSON\",\n    schema=schema,\n    max_retries=3,\n    generate=lambda prompt, context: llm.generate(prompt),\n)\n\nif result.valid:\n    print(result.data)\n    print(len(result.attempts))\nelse:\n    print(result.errors)\n```\n\n`guarded_generate()` validates each generation, repairs when possible, feeds targeted retry prompts back to the generator, and returns every attempt for observability. Pass `repair=False` for strict validation-only loops, `include_message_history=False` to omit prior model output from retry prompts, or `throw_on_failure=True` when invalid output should raise `GuardedGenerationError`.\n\nAsync clients can use `guarded_generate_async()` with the same options.\n\n### Supported Formats\n\nJSON remains the default, so existing code keeps working. Pass `format=` to parse and repair other data formats:\n\n```python\nyaml_result = outputguard.validate_and_repair(\n    \"```yaml\\nname: Alice\\nage: 30\\n```\",\n    schema,\n    format=\"yaml\",\n)\n\ntoml_data = outputguard.parse('name = \"Alice\"\\nage = 30', schema, format=\"toml\")\npython_data = outputguard.parse(\"{'name': 'Alice', 'age': 30}\", schema, format=\"python\")\n\n# Use auto or forced-json-off when the model is not constrained to JSON.\nauto_data = outputguard.parse(\"name: Alice\\nage: 30\", schema, format=\"forced-json-off\")\n```\n\nSupported input formats are `json`, `yaml`\u002F`yml`, `toml`, `python`\u002F`python-literal`, `auto`, and `forced-json-off`.\n\n### Batch Processing\n\nUse batch helpers when validating fixture sets, eval outputs, or logs:\n\n```python\nbatch = outputguard.validate_batch(outputs, schema, repair=True, format=\"auto\")\nprint(batch.summary)\n# BatchSummary(total=..., valid=..., invalid=..., repaired=..., ...)\n\nrepaired = outputguard.repair_batch(outputs)\nprint(repaired.summary.strategy_counts)\n```\n\n### CLI\n\n```bash\n# Validate JSON against a schema\noutputguard validate output.json -s schema.json\n\n# Validate YAML, TOML, Python literal, or auto-detected output\noutputguard validate output.yaml -s schema.json --input-format yaml\noutputguard validate output.toml -s schema.json --input-format toml\noutputguard validate output.txt -s schema.json --input-format forced-json-off\n\n# Validate with auto-repair\noutputguard validate output.json -s schema.json --repair\n\n# Repair only (no schema)\noutputguard repair output.json\noutputguard repair output.yaml --input-format yaml\n\n# Validate a JSON array of output strings\noutputguard batch outputs.json -s schema.json --repair -f json\n\n# Pipe from stdin\necho '{name: \"Alice\", age: 30,}' | outputguard repair -\n\n# Generate a retry prompt\noutputguard retry-prompt output.json -s schema.json\n\n# List all repair strategies\noutputguard strategies\n```\n\n## What It Fixes\n\nFifteen strategies, applied in order. Most target JSON-family malformations; generic strategies such as `strip_fences` also repair fenced YAML, TOML, and Python literal output without converting it to JSON.\n\n| # | Strategy | Before | After |\n|---|---|---|---|\n| 1 | `fix_encoding` | `Ċ{ĊĠ\"a\":Ġ1Ċ}` | `{\"a\": 1}` |\n| 2 | `strip_fences` | `` ```json\\n{\"a\": 1}\\n``` `` | `{\"a\": 1}` |\n| 3 | `extract_json` | `Sure! Here's the JSON: {\"a\": 1} Let me know!` | `{\"a\": 1}` |\n| 4 | `remove_comments` | `{\"a\": 1} \u002F\u002F a comment` | `{\"a\": 1}` |\n| 5 | `fix_commas` | `{\"a\": 1, \"b\": 2,}` | `{\"a\": 1, \"b\": 2}` |\n| 6 | `fix_quotes` | `{'a': 'hello'}` | `{\"a\": \"hello\"}` |\n| 7 | `fix_keys` | `{a: 1, b: 2}` | `{\"a\": 1, \"b\": 2}` |\n| 8 | `fix_values` | `{\"a\": NaN, \"b\": Infinity}` | `{\"a\": null, \"b\": null}` |\n| 9 | `fix_booleans` | `{\"a\": True, \"b\": None}` | `{\"a\": true, \"b\": null}` |\n| 10 | `fix_truncated` | `{\"a\": 1, \"b\": \"hel` | `{\"a\": 1, \"b\": \"hel\"}` |\n| 11 | `fix_ellipsis` | `{\"items\": [1, 2, ...]}` | `{\"items\": [1, 2]}` |\n| 12 | `fix_unicode` | `{\"a\": \"\\u00\"}` | `{\"a\": \"�\"}` |\n| 13 | `fix_inner_quotes` | `{\"a\": \" \"hello\" \"}` | `{\"a\": \" \\\"hello\\\" \"}` |\n| 14 | `fix_closers` | `{\"a\": [1, 2, 3` | `{\"a\": [1, 2, 3]}` |\n| 15 | `fix_newlines` | `{\"a\": \"line1↵line2\"}` | `{\"a\": \"line1\\nline2\"}` |\n\n## Tested Against 288 Real LLM Models\n\nWe tested outputguard against **every text-generation model on OpenRouter** — 288 models across 40+ providers.\n\n**Result: 100% success rate.** Every model's output was either valid JSON or successfully repaired.\n\n| | Count |\n|---|---|\n| Models tested | **288** |\n| Valid immediately | 225 (78%) |\n| Repaired by outputguard | 63 (22%) |\n\nThe 63 repaired outputs were fixed automatically — mostly `strip_fences` (markdown code fences are the #1 LLM JSON issue), plus `extract_json`, `fix_truncated`, and `fix_encoding`.\n\n> *4 models were excluded from testing due to broken API responses (tokenizer corruption, truncated streaming) — not JSON issues.*\n\n\u003Cdetails>\n\u003Csummary>\u003Cstrong>Highlighted model results\u003C\u002Fstrong> (click to expand)\u003C\u002Fsummary>\n\n| Model | Provider | Result | Fix Applied |\n|---|---|---|---|\n| GPT-5 Mini | OpenAI | ✅ Clean | — |\n| GPT-5 Pro | OpenAI | ✅ Clean | — |\n| GPT-4.1 Mini | OpenAI | ✅ Clean | — |\n| Claude Sonnet 4.6 | Anthropic | ✅ Clean | — |\n| Claude Opus 4.7 | Anthropic | ✅ Clean | — |\n| Claude Haiku 4.5 | Anthropic | 🛠️ Repaired | `strip_fences` |\n| Gemini 2.5 Flash | Google | ✅ Clean | — |\n| Gemini 2.5 Pro | Google | 🛠️ Repaired | `strip_fences` |\n| Gemini 3.1 Flash Lite | Google | ✅ Clean | — |\n| Grok 4.1 Fast | xAI | ✅ Clean | — |\n| Grok 4.3 | xAI | ✅ Clean | — |\n| Mistral Medium 3.5 | Mistral | ✅ Clean | — |\n| Mistral Large | Mistral | ✅ Clean | — |\n| DeepSeek v4 Pro | DeepSeek | ✅ Clean | — |\n| DeepSeek v3.2 | DeepSeek | 🛠️ Repaired | `strip_fences` |\n| Llama 4 Maverick | Meta | ✅ Clean | — |\n| Llama 4 Scout | Meta | 🛠️ Repaired | `strip_fences` |\n| Qwen 3.6 Flash | Alibaba | ✅ Clean | — |\n| Qwen 3 Max | Alibaba | ✅ Clean | — |\n| Kimi K2.6 | Moonshot | ✅ Clean | — |\n| GLM 5.1 | Zhipu | ✅ Clean | — |\n| Command A | Cohere | ✅ Clean | — |\n| Phi-4 | Microsoft | 🛠️ Repaired | `strip_fences` |\n| Nova Premier | Amazon | 🛠️ Repaired | `strip_fences` |\n| Seed 1.6 | ByteDance | ✅ Clean | — |\n| Mercury 2 | Inception | ✅ Clean | — |\n\n\u003C\u002Fdetails>\n\n> All 288 raw model outputs are committed as [test fixtures](https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard\u002Ftree\u002Fmaster\u002Ftests\u002Ffixtures\u002Freal_outputs). Run `python -m tests.real_model_runner sweep` to re-test against every model yourself.\n\n### Test Suite\n\n**2,001 tests** across 9 testing dimensions:\n\n| Category | Tests | What it covers |\n|---|---|---|\n| Strategy exhaustive | 159 | Every strategy pushed to edge cases |\n| Adversarial & fuzzing | 286 | 141 chaotic inputs, concurrency, performance |\n| API contracts | 145 | `parse()`, exceptions, reports, CLI, registry |\n| LLM corpus | 119 | Real failure patterns from 7 model families |\n| Combinations | 115 | Multi-strategy interactions, ordering, idempotency |\n| Real model fixtures | 576 | Actual outputs from 288 LLM models |\n| Core & integration | 414 | Strategies, validator, repairer, guard, stress |\n| Format matrix | 74 | Every public JSON API surface repeated for YAML, TOML, Python literals, auto, aliases, and forced-JSON-off |\n| 2.0 orchestration | 10 | Guarded generation, async generation, batch helpers, and batch CLI |\n\n```bash\nuv run pytest tests\u002F -q\n# 2,001 passed\n```\n\n## Configuration\n\nUse the `OutputGuard` class for fine-grained control over which strategies run:\n\n```python\nfrom outputguard import OutputGuard\n\n# Strict mode — only fix formatting, not content\nstrict = OutputGuard(\n    strategies=[\"strip_fences\", \"fix_commas\"],\n    max_repair_attempts=1,\n)\nresult = strict.validate_and_repair(text, schema)\n\n# Aggressive mode — all strategies, more attempts\naggressive = OutputGuard(\n    strategies=None,          # All 15 strategies (default)\n    max_repair_attempts=5,\n)\nresult = aggressive.validate_and_repair(text, schema)\n\n# YAML mode — preserves YAML syntax when repairing fenced output\nyaml_guard = OutputGuard(format=\"yaml\")\nresult = yaml_guard.validate_and_repair(\"```yaml\\nname: Alice\\nage: 30\\n```\", schema)\n```\n\n## RepairReport\n\nFor debugging and observability, `RepairReport` gives you a full breakdown of what happened:\n\n```python\nfrom outputguard.report import RepairReport\n\nreport = RepairReport(\n    original_text=original,\n    final_text=repaired,\n    success=True,\n    steps=steps,\n)\n\nprint(report.summary)\n# Repaired using 2 strategy(ies): strip_fences, fix_commas\n\nprint(report.confidence)   # 0.8 — fewer strategies = higher confidence\nprint(report.diff)         # Unified diff from original to repaired\nprint(report.step_diffs()) # Per-strategy diffs for verbose logging\n```\n\n**Confidence scoring** is a heuristic from 0.0 to 1.0. It decreases as more strategies are needed and as the text changes more. Useful for deciding whether to trust a repair or escalate to a retry.\n\n## API Reference\n\n### Module-level Functions\n\n| Function | Returns | Description |\n|---|---|---|\n| `validate(text, schema, format=\"json\")` | `ValidationResult` | Validate structured output against a schema |\n| `repair(text, format=\"json\")` | `RepairResult` | Auto-repair malformed structured output |\n| `validate_and_repair(text, schema, format=\"json\")` | `ValidationResult` | Validate, repair if needed, re-validate |\n| `parse(text, schema, format=\"json\")` | `dict | list | scalar` | Validate, repair, and return parsed data |\n| `retry_prompt(text, schema, errors, format=\"json\", include_message_history=True)` | `str` | Generate a correction prompt for the LLM |\n| `guarded_generate(...)` | `GuardedGenerateResult` | Retry an arbitrary generator until output validates |\n| `guarded_generate_async(...)` | `GuardedGenerateResult` | Async variant for async LLM clients |\n| `validate_batch(texts, schema, ...)` | `BatchValidationResult` | Validate many outputs and return aggregate diagnostics |\n| `repair_batch(texts, ...)` | `BatchRepairResult` | Repair many outputs and return aggregate diagnostics |\n\n### Classes\n\n| Class | Description |\n|---|---|\n| `OutputGuard` | Configurable pipeline with strategy selection, retry limits, and default `format` |\n| `GuardedGenerateResult` | Result with `valid`, `data`, `text`, `attempts`, `errors`, `repaired`, `strategies_applied`, `exhausted`, `format` |\n| `BatchSummary` | Summary with `total`, `valid`, `invalid`, `repaired`, `parse_failures`, `schema_failures`, `success_rate`, `strategy_counts`, `formats` |\n| `ValidationResult` | Result with `valid`, `data`, `errors`, `repaired`, `strategies_applied`, `format` |\n| `RepairResult` | Result with `repaired`, `text`, `strategies_applied`, `parse_error`, `format` |\n| `ValidationError` | Error detail with `message`, `path`, `schema_path`, `value` |\n| `RepairReport` | Detailed report with `diff`, `confidence`, `summary`, `step_diffs()` |\n\n### Exceptions\n\n| Exception | Description |\n|---|---|\n| `OutputGuardError` | Base exception |\n| `ParseError` | Structured output could not be parsed even after repair |\n| `SchemaValidationError` | Structured output parsed but does not match the schema |\n| `GuardedGenerationError` | `guarded_generate(..., throw_on_failure=True)` could not get valid output |\n| `RepairError` | Repair was attempted but failed |\n| `StrategyError` | A specific repair strategy encountered an error |\n\n## CLI Reference\n\n```\noutputguard [COMMAND] [OPTIONS]\n```\n\n| Command | Description |\n|---|---|\n| `validate INPUT -s SCHEMA` | Validate structured output against a schema |\n| `validate INPUT -s SCHEMA --repair` | Validate with auto-repair |\n| `validate INPUT -s SCHEMA --input-format yaml` | Validate YAML instead of JSON |\n| `repair INPUT` | Repair malformed structured output |\n| `repair INPUT --strategies strip_fences,fix_commas` | Repair with specific strategies |\n| `repair INPUT --input-format forced-json-off` | Repair auto-detected non-JSON output |\n| `batch INPUT -s SCHEMA --repair` | Validate a JSON array of output strings |\n| `retry-prompt INPUT -s SCHEMA [--no-message-history]` | Generate a correction prompt |\n| `strategies` | List all available strategies |\n\nAll commands accept `--input-format` for the data format, `-f json` for machine-readable command output, `-o FILE` to write to a file, and `-` as INPUT to read from stdin.\n\n## Why outputguard?\n\n| | `json.loads()` + regex | outputguard |\n|---|---|---|\n| Repair strategies | Roll your own | 15, tested and ordered |\n| Schema validation | Separate library | Built in (jsonschema) |\n| Retry prompts | Write your own | One function call |\n| Retry orchestration | Write a custom loop | `guarded_generate()` \u002F `guarded_generate_async()` |\n| Batch processing | Ad hoc scripts | `validate_batch()`, `repair_batch()`, CLI `batch` |\n| Confidence scoring | No | Yes |\n| Truncated JSON | Breaks | Recovers |\n| Tests | Probably zero | **2,001** (incl. 288 real LLM models and format matrix coverage) |\n| LLM dependencies | — | None (works with any provider) |\n| Footprint | — | Small runtime set: click, jsonschema, PyYAML, rich, plus tomli on Python 3.10 |\n\noutputguard has no opinion about which LLM you use or whether JSON mode is available. It operates on strings and schemas — plug it into OpenAI, Anthropic, local models, or anything else.\n\n## Examples\n\nSee the [`examples\u002F`](https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard\u002Ftree\u002Fmaster\u002Fexamples) directory for complete, runnable scripts:\n\n- **[basic_usage.py](examples\u002Fbasic_usage.py)** — Core validate\u002Frepair workflow\n- **[retry_loop.py](examples\u002Fretry_loop.py)** — Retry pattern with correction prompts\n- **[guarded_generation.py](examples\u002Fguarded_generation.py)** — Provider-agnostic guarded generation\n- **[custom_pipeline.py](examples\u002Fcustom_pipeline.py)** — Custom strategy configuration\n- **[batch_processing.py](examples\u002Fbatch_processing.py)** — Process multiple outputs with statistics\n\n## Contributing\n\nContributions are welcome. Please open an issue first to discuss what you'd like to change.\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard.git\ncd outputguard\nuv sync --dev\nuv run pytest tests\u002F -v\n```\n\n## TypeScript \u002F JavaScript\n\nLooking for a JS\u002FTS version? See **[outputguard-js](https:\u002F\u002Fgithub.com\u002Fndcorder\u002Foutputguard-js)** — same core API shape, TypeScript-native.\n\n## License\n\n[MIT](LICENSE)\n","outputguard 是一个用于验证、修复和重试大语言模型（LLM）结构化输出的工具。它提供了13种针对常见JSON格式错误的修复策略，支持JSON Schema验证，并能够生成带有反馈的重试提示。项目使用Python编写，适用于处理由AI模型生成的JSON、YAML、TOML以及Python字面量等结构化数据时遇到的解析问题。特别适合需要对AI应用中的输出进行自动校验与修正的场景，如确保从聊天机器人或自动化流程中获取的数据符合预期格式。通过简单的API调用或命令行接口，开发者可以轻松集成这一功能到现有系统中，提高数据处理的健壮性和准确性。","2026-06-11 03:59:09","CREATED_QUERY"]