Normandy.LLM.JsonDeserializer (normandy v0.2.0)
View SourceJSON deserialization helper with automatic error recovery.
This module provides robust JSON deserialization with:
- Automatic retry on JSON parse errors
- Error feedback to LLM via system prompt augmentation
- Configurable retry attempts
- Support for nested/double-encoded JSON
Usage with Agent
# Enable in agent config
agent = BaseAgent.init(%{
client: client,
model: "claude-3-5-sonnet-20241022",
temperature: 0.7,
enable_json_retry: true, # Enable automatic retry
json_retry_max_attempts: 3 # Optional: default is 2
})
# The agent will automatically retry on JSON parse errors
{agent, response} = BaseAgent.run(agent, input)Manual Usage
# With default retries (2)
{:ok, schema} = JsonDeserializer.deserialize_with_retry(
raw_content,
schema,
client,
model,
temperature,
max_tokens,
messages
)
# With custom retries
{:ok, schema} = JsonDeserializer.deserialize_with_retry(
raw_content,
schema,
client,
model,
temperature,
max_tokens,
messages,
max_retries: 3
)How It Works
- Attempts to parse JSON response
- On error, augments system prompt with error details
- Retries LLM call with error feedback
- Repeats until success or max_retries reached
Configuration
Options:
:max_retries- Maximum retry attempts (default: 2):tools- Tool schemas to include in retry:adapter- JSON adapter module (default: from :normandy app config)
Summary
Functions
Deserialize JSON content with automatic retry on errors.
Parse and validate JSON content without retry.
Functions
@spec deserialize_with_retry( String.t(), struct(), struct(), String.t(), float() | nil, integer() | nil, list(), keyword() ) :: {:ok, struct()} | {:error, term()}
Deserialize JSON content with automatic retry on errors.
If initial deserialization fails, this function:
- Extracts the error message
- Augments the system prompt with error details
- Calls the LLM again with feedback
- Attempts deserialization again
Parameters
content- Raw string content from LLMschema- Target schema struct to populateclient- LLM clientmodel- Model nametemperature- Temperature settingmax_tokens- Max tokensmessages- Original message historyopts- Options (:max_retries,:tools,:adapter)
Returns
{:ok, populated_schema}- Success{:error, reason}- Failed after all retries
Parse and validate JSON content without retry.
This is a simpler version of deserialize_with_retry/8 that performs
one-shot parsing and validation without LLM retry. Useful for parsing
final LLM responses where retry is not needed.
Parameters
content- Raw string content from LLMschema- Target schema struct to populateopts- Options (:adapter)
Returns
{:ok, populated_schema}- Success{:error, reason}- Parsing or validation failed
Examples
iex> schema = %BaseAgentOutputSchema{}
iex> JsonDeserializer.parse_and_validate(~s({"chat_message": "Hello"}), schema)
{:ok, %BaseAgentOutputSchema{chat_message: "Hello"}}
iex> JsonDeserializer.parse_and_validate("invalid json", schema)
{:error, {:json_parse_error, reason, content}}