Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

guardflow-java

CI license

Validators and a retry-until-valid guard for LLM output, in Java. The Java port of guardflow (Rust) / guardflow-go — same idea, adapted to Java: no framework dependency, just a Handler (String -> String) decorated the way a Servlet Filter decorates a request handler.

Install

Not published to Maven Central — pull it straight from GitHub via JitPack:

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.thaicn1712</groupId>
    <artifactId>guardflow-java</artifactId>
    <version>main-SNAPSHOT</version> <!-- or a tagged release -->
</dependency>

Usage

Guard guard = Guard.create()
    .with(new NotEmpty())
    .with(new MaxLength(2000));

Handler guarded = GuardFlow.withGuard(myLlmHandler, guard, 3); // up to 3 attempts

String output = guarded.run("what does the fox say?");

myLlmHandler is any Handler — String run(String input) throws Exception, the shape most LLM call wrappers in Java already have. No interface to implement beyond that, no framework to adopt.

Built-in validators

NotEmpty, MaxLength, MinLength, MatchesRegex, OneOf, ValidJson, NoPii (email/phone pattern match), Profanity (word-list match), Truncate (never fails outright — offers a truncated fix instead).

Fixing instead of rejecting

Some validators (like Truncate) can repair what they'd otherwise reject. Guard.fix applies that repair and re-checks:

Guard guard = Guard.create().with(new Truncate(280));
Guard.FixResult result = guard.fix(tooLongText); // result.text() truncated to 280 code points, result.outcome().passed() == true

Async validators

For checks that need network access — a moderation API, an LLM-as-judge call — implement AsyncValidator instead of Validator, and use AsyncGuard / GuardFlow.withAsyncGuard. It's a plain blocking call rather than CompletableFuture chaining: on modern Java, run it on a virtual thread and blocking costs nothing.

class ModerationCheck implements AsyncValidator {
    public ValidationOutcome validate(String text) throws Exception {
        var result = client.check(text);
        return result.flagged()
            ? ValidationOutcome.fail(result.reason())
            : ValidationOutcome.pass();
    }
}

AsyncGuard guard = AsyncGuard.create().with(new ModerationCheck());
Handler guarded = GuardFlow.withAsyncGuard(myLlmHandler, guard, 3);

Examples

mvn -q compile exec:java -Dexec.mainClass=io.github.thaicn1712.guardflow.examples.RetryUntilValidExample

License

MIT

About

Validators and a retry-until-valid guard for LLM output, in Java

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages