Implement Structured Output with Pydantic Models#16
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces structured output support to the ChatGradient client, enabling automatic parsing and validation of LLM responses into Pydantic models. The implementation adds a with_structured_output() method that returns a wrapper handling JSON parsing and Pydantic validation.
Key Changes:
- Added
with_structured_output()method to ChatGradient that returns a StructuredChatGradient wrapper - Implemented JSON parsing and Pydantic validation with error handling for both single and multiple object responses
- Added comprehensive unit tests using a mock LLM to validate functionality without network calls
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| langchain_gradient/chat_models.py | Implements with_structured_output() method and StructuredChatGradient wrapper class with JSON parsing and Pydantic validation |
| tests/unit_tests/test_structured_output.py | Adds unit tests covering success cases, invalid JSON handling, and validation errors using a dummy LLM |
| README.md | Documents the new structured output feature with usage example |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # If response_format exists, append it to the messages as a system hint | ||
| if rf: | ||
| # inject formatting instruction as a system message at the start | ||
| messages = [BaseMessage(content=str(rf))] + messages # type: ignore |
There was a problem hiding this comment.
Creating a BaseMessage directly is incorrect. BaseMessage is likely an abstract base class from langchain_core.messages. Use a concrete message type like SystemMessage instead: from langchain_core.messages import SystemMessage and messages = [SystemMessage(content=str(rf))] + messages.
|
|
||
| try: | ||
| parsed = json.loads(raw) | ||
| except Exception as e: # noqa: BLE001 - we want to catch JSON errors |
There was a problem hiding this comment.
Catching broad Exception is too permissive. Catch json.JSONDecodeError specifically to handle JSON parsing errors while allowing other exceptions to propagate normally.
| except Exception as e: # noqa: BLE001 - we want to catch JSON errors | |
| except json.JSONDecodeError as e: |
Summary
Adds structured output support to the ChatGradient client by introducing with_structured_output(). This returns a lightweight wrapper that parses the model's text output as JSON and validates it using a provided Pydantic model, returning typed BaseModel instances (or lists of instances).
What changed
chat_models.py
-Added with_structured_output() to ChatGradient.
-Added StructuredChatGradient helper wrapper which:
-Invokes the underlying LLM,
-Parses string output as JSON,
-Validates using Pydantic and returns model instances (or lists when multiple=True.
-Handles parsing and validation errors with clear ValueError messages.
test_structured_output.py (new)
-Unit tests for single-object success, multiple-object success, invalid JSON, and validation error cases. Tests are isolated and do not hit the network (use a small dummy LLM).
README.md
Example usage showing with_structured_output(Person)
fixes #10