feat: use json-repair for LLM output parsing - #954
Conversation
There was a problem hiding this comment.
Pull request overview
This PR enhances JSON parsing robustness for LLM-generated outputs by integrating the json-repair library. LLMs occasionally produce malformed JSON (e.g., trailing commas, single quotes), which causes standard json.loads() to fail. The change targets only direct LLM output parsing locations while preserving standard JSON operations elsewhere for efficiency.
Changes:
- Added
json-repair>=0.54dependency - Updated LLM output parsing in evaluation judge files and language model implementations to use
repair_json - Broadened exception handling from
JSONDecodeErrorto genericExceptionin OpenAI language models
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Adds json-repair library dependency |
| evaluation/locomo/episodic_memory/llm_judge.py | Uses repair_json for parsing LLM judge responses |
| evaluation/locomo/episodic_agent/llm_judge.py | Uses repair_json for parsing LLM judge responses |
| src/memmachine/common/language_model/amazon_bedrock_language_model.py | Uses repair_json for parsing Bedrock structured outputs |
| src/memmachine/common/language_model/openai_responses_language_model.py | Uses repair_json for parsing function call arguments and broadens exception handling |
| src/memmachine/common/language_model/openai_chat_completions_language_model.py | Uses repair_json for parsing function call arguments and broadens exception handling |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@malatewang @o-love I think this would be helpful when LLM doesn't return a correct json. |
|
I've updated the code to properly catch
|
|
Hi @ProgrammerPlus1998, thanks for the updates. I triggered the CI, and some unit tests failed due to the changes. Those tests appear to be validating invalid JSON inputs. You may want to remove them or adjust them to use inputs that even There are also many lint errors in the Additionally, I noticed that some of your commits are signed, but not all of them. We require all commits to be signed before merging. The easiest way to address this would be to squash the commits and sign the resulting commit. Let me know if you have any questions. |
- Add json-repair library to handle common LLM JSON formatting errors - Update language model implementations (OpenAI, Bedrock) to use json-repair - Fix unit tests to validate JSON repair instead of expecting errors - Use real MemMachine examples in tests (project creation, memory search) - Remove unused json imports after json-repair integration This change improves robustness when handling LLM outputs with malformed JSON (unquoted keys, single quotes, trailing commas, etc.)
38c3997 to
5cc565c
Compare
|
Hi @jealous ,
|
|
I triggered the CI and looks like there are still some issues. Could you please run following command locally in the project's root folder to check:
|
- Fix import sorting (I001) in 4 files - Sort imports alphabetically and place json_repair correctly - evaluation/locomo/episodic_agent/llm_judge.py - evaluation/locomo/episodic_memory/llm_judge.py - src/memmachine/common/language_model/openai_chat_completions_language_model.py - src/memmachine/common/language_model/openai_responses_language_model.py - Fix code style issues in test files - Remove whitespace from blank lines (W293) - Replace single quotes with double quotes in multiline strings (Q001) - Rename unused unpacked variables to _content (RUF059) - tests/memmachine/common/language_model/test_openai_chat_completions_language_model.py - tests/memmachine/common/language_model/test_openai_responses_language_model.py All ruff checks now pass successfully.
# Conflicts: # uv.lock
Add json-repair v0.55.0 to lock file for LLM output parsing.
|
Hi! Great catch - I've fixed everything! 🎉 ✅ Ruff checks: All passing now!
✅ UV lock conflicts: Completely resolved!
✅ Type checking: Will verify with Everything's pushed and ready for review. The CI should be all green now! 🟢 Thanks for the thorough feedback - really appreciate it! Let me know if anything else needs attention. |
|
@jealous I've reviewed the error logs but I'm having trouble understanding the root cause and whether it's related to my recent changes. Could you help investigate this issue? Thanks! |
|
I don't think it's related to your change. I just triggered a re-run for that job. I think everything should be find. Really appreciate your contribution. |
This reverts commit 1d7866f.
* feat: use json-repair for malformed LLM JSON output recovery - Add json-repair library to handle common LLM JSON formatting errors - Update language model implementations (OpenAI, Bedrock) to use json-repair - Fix unit tests to validate JSON repair instead of expecting errors - Use real MemMachine examples in tests (project creation, memory search) - Remove unused json imports after json-repair integration This change improves robustness when handling LLM outputs with malformed JSON (unquoted keys, single quotes, trailing commas, etc.) * fix: resolve ruff linting issues - Fix import sorting (I001) in 4 files - Sort imports alphabetically and place json_repair correctly - evaluation/locomo/episodic_agent/llm_judge.py - evaluation/locomo/episodic_memory/llm_judge.py - src/memmachine/common/language_model/openai_chat_completions_language_model.py - src/memmachine/common/language_model/openai_responses_language_model.py - Fix code style issues in test files - Remove whitespace from blank lines (W293) - Replace single quotes with double quotes in multiline strings (Q001) - Rename unused unpacked variables to _content (RUF059) - tests/memmachine/common/language_model/test_openai_chat_completions_language_model.py - tests/memmachine/common/language_model/test_openai_responses_language_model.py All ruff checks now pass successfully. * chore: add json-repair dependency to uv.lock Add json-repair v0.55.0 to lock file for LLM output parsing.
* feat: use json-repair for malformed LLM JSON output recovery - Add json-repair library to handle common LLM JSON formatting errors - Update language model implementations (OpenAI, Bedrock) to use json-repair - Fix unit tests to validate JSON repair instead of expecting errors - Use real MemMachine examples in tests (project creation, memory search) - Remove unused json imports after json-repair integration This change improves robustness when handling LLM outputs with malformed JSON (unquoted keys, single quotes, trailing commas, etc.) * fix: resolve ruff linting issues - Fix import sorting (I001) in 4 files - Sort imports alphabetically and place json_repair correctly - evaluation/locomo/episodic_agent/llm_judge.py - evaluation/locomo/episodic_memory/llm_judge.py - src/memmachine/common/language_model/openai_chat_completions_language_model.py - src/memmachine/common/language_model/openai_responses_language_model.py - Fix code style issues in test files - Remove whitespace from blank lines (W293) - Replace single quotes with double quotes in multiline strings (Q001) - Rename unused unpacked variables to _content (RUF059) - tests/memmachine/common/language_model/test_openai_chat_completions_language_model.py - tests/memmachine/common/language_model/test_openai_responses_language_model.py All ruff checks now pass successfully. * chore: add json-repair dependency to uv.lock Add json-repair v0.55.0 to lock file for LLM output parsing.
Purpose of the change
Improve JSON parsing robustness for LLM-generated outputs. Large language models sometimes produce non-standard JSON format (trailing commas, single quotes, missing quotes, etc.), causing parse failures with standard
json.loads(). This PR usesjson-repairlibrary to automatically fix and parse malformed JSON from LLM outputs while maintaining efficiency by only applying it where needed.Description
This PR replaces
json.loads()withrepair_json()from thejson-repairlibrary specifically for parsing direct LLM outputs. The change improves error tolerance when models produce non-standard JSON format without impacting performance of standard JSON parsing operations.Changes:
json-repair>=0.54dependency topyproject.tomlrepair_jsonfor parsing model responsesrepair_jsonfor parsing structured outputs from textrepair_jsonfor function call arguments parsingScope: This change only affects parsing of direct LLM text outputs. API responses and file I/O operations continue to use standard
jsonmodule to maintain efficiency.Fixes/Closes
N/A - This is a preventive improvement rather than fixing a specific reported issue.
Type of change
How Has This Been Tested?
Test Steps:
repair_jsonis only used for LLM output parsingjson.load/loads/dump/dumpsremain for API responses and file operationsTest Results:
Checklist
Maintainer Checklist
Screenshots/Gifs
N/A
Further comments
Performance Note: The
json-repairlibrary is slightly slower than standardjson.loads()but provides much better error tolerance. By limiting its use to only LLM output parsing (where malformed JSON is more likely), we balance robustness and efficiency.Modified Files:
evaluation/locomo/episodic_agent/llm_judge.py- LLM judge response parsingevaluation/locomo/episodic_memory/llm_judge.py- LLM judge response parsingsrc/memmachine/common/language_model/amazon_bedrock_language_model.py- Bedrock structured output parsingsrc/memmachine/common/language_model/openai_responses_language_model.py- OpenAI function call argumentssrc/memmachine/common/language_model/openai_chat_completions_language_model.py- OpenAI function call arguments