RAG + multi-agent (retrieval, policy-compliance, drafting) support assistant for a fictional shipping company, built in Rust with Qdrant for vector storage and a hand-rolled Anthropic tool-calling client (no Rust pydantic-ai equivalent exists). A deterministic supervisor orchestrates the agents and runs every response through a rule-based guardrail pipeline with an append-only audit log. Includes a 44-example golden dataset (normal/injection/policy- violation/hallucination-bait/out-of-scope) and a regression harness that scores retrieval, generation, and guardrail correctness separately, plus a write-up of the failure modes and trade-offs. Co-Authored-By: Claude Sonnet 5 <[email protected]>
45 lines
1.7 KiB
Rust
45 lines
1.7 KiB
Rust
//! Regex patterns backing the deterministic (rule-based) guardrail layer.
|
|
//!
|
|
//! These are a fast, cheap first line of defense -- they catch the
|
|
//! obvious cases before the query or draft ever reaches an LLM call, and
|
|
//! they log independently of whatever the policy-compliance agent decides,
|
|
//! so a policy-agent mistake doesn't silently erase the finding.
|
|
|
|
use regex::Regex;
|
|
|
|
pub struct NamedPattern {
|
|
pub rule_id: &'static str,
|
|
pub regex: Regex,
|
|
}
|
|
|
|
/// Heuristics for prompt-injection / instruction-override attempts.
|
|
pub fn injection_patterns() -> Vec<NamedPattern> {
|
|
build(&[
|
|
("injection.ignore_instructions", r"(?i)ignore (all )?(previous|prior|above) instructions"),
|
|
("injection.role_override", r"(?i)you are now|act as (a|an)|pretend (you are|to be)"),
|
|
("injection.reveal_prompt", r"(?i)(reveal|show|print) (your|the) (system prompt|instructions)"),
|
|
("injection.developer_mode", r"(?i)developer mode|jailbreak|do anything now|\bDAN\b"),
|
|
("injection.new_rules", r"(?i)new rules?:|from now on,? you"),
|
|
])
|
|
}
|
|
|
|
/// Heuristics for likely PII in a piece of text (used to catch a draft
|
|
/// response accidentally echoing something it shouldn't).
|
|
pub fn pii_patterns() -> Vec<NamedPattern> {
|
|
build(&[
|
|
("pii.credit_card", r"\b(?:\d[ -]?){13,16}\b"),
|
|
("pii.ssn_like", r"\b\d{3}-\d{2}-\d{4}\b"),
|
|
("pii.email", r"\b[\w.+-]+@[\w-]+\.[\w.-]+\b"),
|
|
])
|
|
}
|
|
|
|
fn build(specs: &[(&'static str, &str)]) -> Vec<NamedPattern> {
|
|
specs
|
|
.iter()
|
|
.map(|(rule_id, pattern)| NamedPattern {
|
|
rule_id,
|
|
regex: Regex::new(pattern).expect("guardrail regex is valid"),
|
|
})
|
|
.collect()
|
|
}
|