Make all json parsing less strict by default (#15287)

- Enables strict=False by default
- Uses partial json recovery logic by default

<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes if applicable,
  - **Dependencies:** any dependencies required for this change,
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in
`docs/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
This commit is contained in:
Nuno Campos 2023-12-28 14:48:53 -08:00 committed by GitHub
parent bc5a0ef6ca
commit f74151b4e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 4 additions and 3 deletions

View File

@ -114,7 +114,7 @@ def parse_partial_json(s: str, *, strict: bool = False) -> Any:
def parse_json_markdown( def parse_json_markdown(
json_string: str, *, parser: Callable[[str], Any] = json.loads json_string: str, *, parser: Callable[[str], Any] = parse_partial_json
) -> dict: ) -> dict:
""" """
Parse a JSON string from a Markdown string. Parse a JSON string from a Markdown string.
@ -190,7 +190,7 @@ class JsonOutputParser(BaseCumulativeTransformOutputParser[Any]):
def parse(self, text: str) -> Any: def parse(self, text: str) -> Any:
text = text.strip() text = text.strip()
try: try:
return parse_json_markdown(text.strip(), parser=parse_partial_json) return parse_json_markdown(text.strip())
except JSONDecodeError as e: except JSONDecodeError as e:
raise OutputParserException(f"Invalid json output: {text}") from e raise OutputParserException(f"Invalid json output: {text}") from e

View File

@ -1,4 +1,5 @@
"""Evaluators for parsing strings.""" """Evaluators for parsing strings."""
import json
from operator import eq from operator import eq
from typing import Any, Callable, Optional, Union, cast from typing import Any, Callable, Optional, Union, cast
@ -68,7 +69,7 @@ class JsonValidityEvaluator(StringEvaluator):
""" """
try: try:
parse_json_markdown(prediction) parse_json_markdown(prediction, parser=json.loads)
return {"score": 1} return {"score": 1}
except Exception as e: except Exception as e:
return {"score": 0, "reasoning": str(e)} return {"score": 0, "reasoning": str(e)}