Skip to content

Commit 1db6dba

Browse files
committed
Add Guardrails functionality and tests to the 'tool-guardrails' sample
- Add the functionality - Rename `tool-guardrails` to `guardrails` - Change the README - Add an ability to run with the platform BOMs
1 parent 2a94f69 commit 1db6dba

File tree

18 files changed

+219
-40
lines changed

18 files changed

+219
-40
lines changed

samples/chatbot/src/test/java/io/quarkiverse/langchain4j/tests/rag/RAGTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ public void documentBasedAnswer() throws InterruptedException, URISyntaxExceptio
119119
boolean second = line.contains("""
120120
gen_ai_token_type="output"
121121
""".trim());
122-
return first && second;
122+
boolean third = line.contains("Bot");
123+
return first && second && third;
123124
})
124125
.orElseThrow(() -> new AssertionError("There is no metric for output tokens!"));
125126
assertTrue(outputTokensMetric.contains("ai_service_class_name=\"io.quarkiverse.langchain4j.sample.chatbot.Bot\""));
Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Tool Guardrails Demo
22

3-
This demo showcases the implementation of **guardrails for tool/function calling** in Quarkus LangChain4j.
3+
This demo showcases the implementation of **guardrails** in Quarkus LangChain4j, including tool/function calling.
44
Guardrails provide a mechanism to validate and control tool invocations at both input and output stages.
55

6-
## What are Tool Guardrails?
6+
## What are Guardrails?
77

8-
Tool guardrails are validation and transformation mechanisms that:
8+
Guardrails are validation and transformation mechanisms that:
99

10-
- **Input Guardrails**: Validate parameters and context before tool execution
11-
- **Output Guardrails**: Validate, filter, or transform tool results before returning to the LLM
10+
- **Input Guardrails**: Validate parameters and context before execution
11+
- **Output Guardrails**: Validate, filter, or transform results before returning to the LLM
1212

1313
This enables:
1414
- Security controls (authorization, authentication)
@@ -19,7 +19,7 @@ This enables:
1919

2020
## Demo Overview
2121

22-
This demo includes 6 different guardrails demonstrating various use cases:
22+
This demo includes 7 different guardrails demonstrating various use cases:
2323

2424
### Input Guardrails
2525

@@ -53,13 +53,17 @@ This demo includes 6 different guardrails demonstrating various use cases:
5353
6. **Combined Guardrails** - Multiple guardrails on one tool
5454
- Demonstrates guardrail chaining
5555
- Ordered execution
56+
57+
7. **Profanity Guardrail** - Validation of AI output.
58+
- The simplest use case to show the basics
59+
- Checks chat AI output, fails if it contains prohibited word
5660

5761
## Running the Demo
5862

5963
### Start the application in dev mode:
6064

6165
```bash
62-
mvn quarkus:dev
66+
mvn quarkus:dev -Dquarkus.langchain4j.openai.api-key=$API_KEY
6367
```
6468

6569
The application will start on http://localhost:8080
@@ -99,3 +103,14 @@ done
99103
# Large result set will be truncated
100104
curl "http://localhost:8080/email?request=Search%20for%20all%20customers"
101105
```
106+
107+
108+
#### 4. Chat with the assistant (with output moderation)
109+
110+
```bash
111+
$ curl -X POST localhost:8080/chatbot/moderated -w "\n" -d 'Hello, my name is Meatbag'
112+
[The AI answered with expletive]
113+
# The similar but non-prohibited name will not be flagged
114+
$ curl -X POST localhost:8080/chatbot/moderated -w "\n" -d 'Hello, my name is Fleabag'
115+
Hello Fleabag! How can I assist you today?
116+
```
Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<modelVersion>4.0.0</modelVersion>
44

55
<groupId>io.quarkiverse.langchain4j</groupId>
6-
<artifactId>quarkus-langchain4j-sample-tool-guardrails</artifactId>
7-
<name>Quarkus LangChain4j - Sample - Tool Guardrails</name>
6+
<artifactId>quarkus-langchain4j-sample-guardrails</artifactId>
7+
<name>Quarkus LangChain4j - Sample - Guardrails</name>
88
<version>1.0-SNAPSHOT</version>
99

1010
<properties>
@@ -16,52 +16,31 @@
1616
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
1717
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
1818
<quarkus.platform.version>3.27.1</quarkus.platform.version>
19+
<skipTests>true</skipTests>
1920
<skipITs>true</skipITs>
2021
<surefire-plugin.version>3.2.5</surefire-plugin.version>
21-
<quarkus-langchain4j.version>999-SNAPSHOT</quarkus-langchain4j.version>
2222
</properties>
2323

24-
<dependencyManagement>
25-
<dependencies>
26-
<dependency>
27-
<groupId>${quarkus.platform.group-id}</groupId>
28-
<artifactId>${quarkus.platform.artifact-id}</artifactId>
29-
<version>${quarkus.platform.version}</version>
30-
<type>pom</type>
31-
<scope>import</scope>
32-
</dependency>
33-
</dependencies>
34-
</dependencyManagement>
35-
3624
<dependencies>
3725
<dependency>
3826
<groupId>io.quarkus</groupId>
3927
<artifactId>quarkus-rest-jackson</artifactId>
4028
</dependency>
4129
<dependency>
42-
<groupId>io.quarkiverse.langchain4j</groupId>
43-
<artifactId>quarkus-langchain4j-openai</artifactId>
44-
<version>${quarkus-langchain4j.version}</version>
30+
<groupId>io.quarkus</groupId>
31+
<artifactId>quarkus-security</artifactId>
4532
</dependency>
4633
<dependency>
4734
<groupId>io.quarkus</groupId>
48-
<artifactId>quarkus-security</artifactId>
35+
<artifactId>quarkus-junit5</artifactId>
36+
<scope>test</scope>
4937
</dependency>
50-
51-
<!-- Minimal dependencies to constrain the build -->
5238
<dependency>
53-
<groupId>io.quarkiverse.langchain4j</groupId>
54-
<artifactId>quarkus-langchain4j-openai-deployment</artifactId>
55-
<version>${quarkus-langchain4j.version}</version>
39+
<groupId>io.rest-assured</groupId>
40+
<artifactId>rest-assured</artifactId>
5641
<scope>test</scope>
57-
<type>pom</type>
58-
<exclusions>
59-
<exclusion>
60-
<groupId>*</groupId>
61-
<artifactId>*</artifactId>
62-
</exclusion>
63-
</exclusions>
6442
</dependency>
43+
6544
</dependencies>
6645

6746
<build>
@@ -96,6 +75,70 @@
9675
</build>
9776

9877
<profiles>
78+
<profile>
79+
<id>default-project-deps</id>
80+
<activation>
81+
<property>
82+
<name>!platform-deps</name>
83+
</property>
84+
</activation>
85+
<properties>
86+
<quarkus-langchain4j.version>999-SNAPSHOT</quarkus-langchain4j.version>
87+
</properties>
88+
<dependencyManagement>
89+
<dependencies>
90+
<dependency>
91+
<groupId>${quarkus.platform.group-id}</groupId>
92+
<artifactId>${quarkus.platform.artifact-id}</artifactId>
93+
<version>${quarkus.platform.version}</version>
94+
<type>pom</type>
95+
<scope>import</scope>
96+
</dependency>
97+
</dependencies>
98+
</dependencyManagement>
99+
<dependencies>
100+
<dependency>
101+
<groupId>io.quarkiverse.langchain4j</groupId>
102+
<artifactId>quarkus-langchain4j-openai</artifactId>
103+
<version>${quarkus-langchain4j.version}</version>
104+
</dependency>
105+
</dependencies>
106+
</profile>
107+
<profile>
108+
<id>platform-deps</id>
109+
<activation>
110+
<property>
111+
<name>platform-deps</name>
112+
</property>
113+
</activation>
114+
<properties>
115+
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
116+
</properties>
117+
<dependencyManagement>
118+
<dependencies>
119+
<dependency>
120+
<groupId>${quarkus.platform.group-id}</groupId>
121+
<artifactId>${quarkus.platform.artifact-id}</artifactId>
122+
<version>${quarkus.platform.version}</version>
123+
<type>pom</type>
124+
<scope>import</scope>
125+
</dependency>
126+
<dependency>
127+
<groupId>${quarkus.platform.group-id}</groupId>
128+
<artifactId>quarkus-langchain4j-bom</artifactId>
129+
<version>${quarkus.platform.version}</version>
130+
<type>pom</type>
131+
<scope>import</scope>
132+
</dependency>
133+
</dependencies>
134+
</dependencyManagement>
135+
<dependencies>
136+
<dependency>
137+
<groupId>io.quarkiverse.langchain4j</groupId>
138+
<artifactId>quarkus-langchain4j-openai</artifactId>
139+
</dependency>
140+
</dependencies>
141+
</profile>
99142
<profile>
100143
<id>native</id>
101144
<activation>

samples/tool-guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailFormatValidator.java renamed to samples/guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailFormatValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public ToolInputGuardrailResult validate(ToolInputGuardrailRequest request) {
5656
return ToolInputGuardrailResult.success();
5757

5858
} catch (Exception e) {
59-
return ToolInputGuardrailResult.failure(
59+
return ToolInputGuardrailResult.fatal(
6060
"Failed to validate email format: " + e.getMessage(), e);
6161
}
6262
}

samples/tool-guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailResource.java renamed to samples/guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailResource.java

File renamed without changes.

samples/tool-guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailService.java renamed to samples/guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailService.java

File renamed without changes.

samples/tool-guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailTools.java renamed to samples/guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/EmailTools.java

File renamed without changes.

samples/tool-guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/OutputSizeLimiter.java renamed to samples/guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/OutputSizeLimiter.java

File renamed without changes.

samples/tool-guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/RateLimitGuardrail.java renamed to samples/guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/RateLimitGuardrail.java

File renamed without changes.

samples/tool-guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/SensitiveDataFilter.java renamed to samples/guardrails/src/main/java/io/quarkiverse/langchain4j/sample/guardrails/SensitiveDataFilter.java

File renamed without changes.

0 commit comments

Comments
 (0)