You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/modules/ROOT/pages/guardrails.adoc
+78-32Lines changed: 78 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -518,62 +518,108 @@ It may happen that the output generated by the LLM is not completely satisfying,
518
518
{"name":"Alex", age:18} Alex is 18 since he became an adult a few days ago.
519
519
----
520
520
521
-
In this situation it is better to try to programmatically trim the json part of the response and check if we can deserialize a valid Person object out of it, before trying to reprompt the LLM again. If the programmatic extraction of the json string from the partially hallucinated LLM output succeeds, it is possible to propagate the rewritten output through the `successWith` method as in the following example.
521
+
In this situation it is better to try to programmatically trim the json part of the response and check if we can deserialize a valid Person object out of it, before trying to reprompt the LLM again. If the programmatic extraction of the json string from the partially hallucinated LLM output succeeds, it is possible to propagate the rewritten output through the `successWith` method.
522
+
523
+
This scenario is so common that it is already provided an abstract class implementing the `OutputGuardrail` interface and performing this programmatic json sanitization out-of-the-box.
This implementation, first tries to deserialize the LLM response into the expected class to be returned by the data extraction. If this doesn't succeed it tries to trim away the non-json part of the response and perform the deserialization again. Note that in both case together with the json response, either the original LLM one or the one programmatically trimmed, the `successWith` method also returns the resulting deserialized object, so that it could be used directly as the final response of the data extraction, instead of uselessly having to execute a second deserialization. In case that both these attempts of deserialization fail then the `OutputGuardrail` perform a reprompt, hoping that the LLM will finally produce a valid json string.
585
+
586
+
In this way if for example there is an AI service trying to extract the data of a customer from the user prompts like the following
587
+
588
+
[source,java]
589
+
----
590
+
@RegisterAiService
591
+
public interface CustomerExtractor {
592
+
593
+
@UserMessage("Extract information about a customer from this text '{text}'. The response must contain only the JSON with customer's data and without any other sentence.")
it is possible to use with it an `OutputGuardrail` that sanitizes the json LLM response by simply extending the former abstract class and declaring which is the expected output class of the data extraction.
600
+
601
+
[source,java]
602
+
----
603
+
@ApplicationScoped
604
+
public class CustomerExtractionOutputGuardrail extends AbstractJsonExtractorOutputGuardrail {
605
+
606
+
@Override
607
+
protected Class<?> getOutputClass() {
608
+
return Customer.class;
609
+
}
610
+
}
611
+
----
612
+
613
+
Note that if the data extraction requires a generified Java type, like a `List<Customer>`, it is conversely necessary to extend the `getOutputType` and return a Jackson's `TypeReference` as it follows:
614
+
615
+
[source,java]
616
+
----
617
+
@ApplicationScoped
618
+
public class CustomersExtractionOutputGuardrail extends AbstractJsonExtractorOutputGuardrail {
0 commit comments