agentscope-ai / agentscope-ai/agentscope-java
[Bug]:Schema Validation Error with Reused Objects in Structured Output
- Linguagem predominante
- Java
- Estrelas
- 5.6k
- Forks
- 1.3k
- Merge médio
- 4d 12h
- PRs com merge (30d)
- 77
Descrição
# Bug Report: Schema Validation Error with Reused Objects in Structured Output
**AgentScope-Java is an open-source project. To involve a broader community, we recommend asking your questions in English.**
## Describe the bug
When using structured output with reused objects (i.e., the same class used multiple times in a parent class), the framework generates a JSON Schema with `$defs` and `$ref` references. However, during parameter validation, the schema validator fails to resolve these references, resulting in a `Schema validation error: Reference /$defs/Address cannot be resolved` error.
This prevents the use of reusable object structures in structured output, which is a common and important pattern for complex data extraction scenarios.
## To Reproduce
Steps to reproduce the behavior:
### 1. Your code
Create a structured output class with reused objects:
```java
/** Schema for order information with address reuse. */
public static class OrderInfo {
public String orderId;
public String orderStatus;
public String customerName;
public String customerPhone;
public String customerEmail;
public Address billingAddress; // Reused Address class
public Address shippingAddress; // Reused Address class (same as billingAddress)
public List items;
public Double subtotal;
public Double tax;
public Double shippingFee;
public Double totalAmount;
public String paymentMethod;
public String createdAt;
public String updatedAt;
public OrderInfo() {}
}
/** Address information - reused in billing and shipping. */
public static class Address {
public String province;
public String city;
public String district;
public String street;
public String postalCode;
public String recipientName;
public String recipientPhone;
public Address() {}
}
/** Order item. */
public static class OrderItem {
public String productName;
public String productId;
public Integer quantity;
public Double unitPrice;
public Double subtotal;
public OrderItem() {}
}
```
Use the class with ReActAgent:
```java
/** Example 5: Extract order information with nested structures. */
private static void runOrderExtractionExample(ReActAgent agent) {
String query =
"Order ID: ORD20260409001, Customer: Zhang San (Phone: 13800138000, Email: zhangsan@example.com). "
+ "Shipping Address: 88 Jianguo Road, Chaoyang District, Beijing, Postal Code 100022, Recipient: Li Si, Phone: 13900139000. "
+ "Billing Address: 1 Zhongguancun Street, Haidian District, Beijing, Postal Code 100080, Recipient: Zhang San, Phone: 13800138000. "
+ "Ordered Items: iPhone 15 Pro (Product ID: IP15PRO) 2 units, Unit Price: 8999 CNY, Subtotal: 17998 CNY; "
+ "AirPods Pro (Product ID: APPRO) 1 unit, Unit Price: 1899 CNY, Subtotal: 1899 CNY. "
+ "Subtotal: 19897 CNY, Tax: 1193.82 CNY, Shipping Fee: 0 CNY, Total: 21090.82 CNY. "
+ "Payment Method: Alipay. Order Status: Paid. "
+ "Created At: 2026-04-09T10:30:00+08:00, Updated At: 2026-04-09T11:00:00+08:00.";
System.out.println("Order Description: " + query);
System.out.println("\nExtracting order information...\n");
Msg userMsg =
Msg.builder()
.role(MsgRole.USER)
.content(
TextBlock.builder()
.text("Extract order information from the following text: " + query)
.build())
.build();
try {
Msg msg = agent.call(userMsg, OrderInfo.class).block();
OrderInfo result = msg.getStructuredData(OrderInfo.class);
System.out.println("========== Extracted Order Information ==========");
} catch (Exception e) {
System.err.println("错误: " + e.getMessage());
e.printStackTrace();
}
}
```
### 2. How to execute
Run the code with a valid LLM model configuration. The error occurs during the agent's tool execution phase when it tries to validate the structured output schema.
### 3. See error
```
14:17:51.702 [boundedElastic-1] DEBUG io.agentscope.core.tool.ToolExecutor - Parameter validation failed for tool 'generate_response': Schema validation error: Reference /$defs/Address cannot be resolved
```
## Expected behavior
The framework should correctly handle JSON Schema references (`$defs` and `$ref`) during parameter validation. When a class is reused multiple times in a structured output, the generated schema should properly define the reusable type in `$defs` and reference it using `$ref`, and the validator should be able to resolve these references.
The expected behavior is:
1. The framework generates a JSON Schema with `$defs` for reused classes
2. The schema validator correctly resolves `$ref` references to `$defs`
3. The structured output extraction works correctly with reused objects
## Environment (please complete the following information):
- **AgentScope-Java Version**: 1.0.11
- **Java Version**: 21 (also tested with 17)
- **OS**: macOS
## Additional context
### Root Cause Analysis
The issue appears to be in the schema validation logic within `io.agentscope.core.tool.ToolExecutor`. When the JSON Schema generator (likely using a library like `jsonschema-generator`) creates schemas with `$defs` for reused classes, the validator is unable to resolve the `$ref` references.
This is a critical issue because:
1. **Code Reusability**: Reusing classes in structured output is a common pattern to avoid duplication
2. **Schema Complexity**: Complex real-world scenarios often require reused structures (e.g., billing/shipping addresses, multiple contact persons, etc.)
3. **JSON Schema Best Practices**: Using `$defs` and `$ref` is the recommended approach in JSON Schema specification for avoiding duplication
#### Deeper Analysis: Schema Structure Issue
After further investigation, the root cause appears to be that **the reused object definitions (`$defs`) are not being defined at the top level of the generated schema JSON**.
**Actual Generated Schema (from debug logs):**
The following is the actual schema generated by the framework (formatted for readability):
```json
{
"type": "object",
"properties": {
"response": {
"$defs": {
"Address": {
"type": "object",
"properties": {
"city": {"type": "string"},
"district": {"type": "string"},
"postalCode": {"type": "string"},
"province": {"type": "string"},
"recipientName": {"type": "string"},
"recipientPhone": {"type": "string"},
"street": {"type": "string"}
}
}
},
"type": "object",
"properties": {
"billingAddress": {"$ref": "#/$defs/Address"},
"shippingAddress": {"$ref": "#/$defs/Address"},
"orderId": {"type": "string"},
"orderStatus": {"type": "string"},
"customerName": {"type": "string"},
"customerPhone": {"type": "string"},
"customerEmail": {"type": "string"},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"productName": {"type": "string"},
"productId": {"type": "string"},
"quantity": {"type": "integer"},
"unitPrice": {"type": "number"},
"subtotal": {"type": "number"}
}
}
},
"subtotal": {"type": "number"},
"tax": {"type": "number"},
"shippingFee": {"type": "number"},
"totalAmount": {"type": "number"},
"paymentMethod": {"type": "string"},
"createdAt": {"type": "string"},
"updatedAt": {"type": "string"}
}
}
},
"required": ["response"]
}
```
This is a critical issue because:
1. **Code Reusability**: Reusing classes in structured output is a common pattern to avoid duplication
2. **Schema Complexity**: Complex real-world scenarios often require reused structures (e.g., billing/shipping addresses, multiple contact persons, etc.)
3. **JSON Schema Best Practices**: Using `$defs` and `$ref` is the recommended approach in JSON Schema specification for avoiding duplication
4. **Schema Validation**: JSON Schema validators expect `$defs` to be at the root level of the schema for proper reference resolution
### Workaround
Currently, the only workaround is to avoid reusing classes by creating duplicate classes for each usage:
```java
// Instead of reusing Address, create separate classes
public static class BillingAddress {
public String province;
public String city;
// ... duplicate all fields
}
public static class ShippingAddress {
public String province;
public String city;
// ... duplicate all fields
}
```
This workaround is not ideal as it leads to code duplication and maintenance issues.
### Suggested Fix
The schema validator should be configured to properly resolve JSON Schema references. This might involve:
1. Using a JSON Schema validator library that supports `$ref` resolution
2. Configuring the validator with a proper schema loader that can resolve references
3. Pre-processing the schema to inline all references before validation
### Related Libraries
The project uses:
- `jsonschema-generator` (version 4.38.0) for schema generation
- `json-schema-validator` (version 3.0.1) for validation
Both libraries support `$defs` and `$ref`, so the issue is likely in how they are integrated in AgentScope.
### Impact
This bug affects any use case that requires:
- Multiple addresses (billing, shipping, etc.)
- Multiple contact persons (customer, recipient, etc.)
- Any other scenario where the same data structure is used multiple times
It significantly limits the practical applicability of structured output in real-world scenarios.
Guia de contribuição
Avaliação
Esta issue ainda não foi avaliada.