Add Maritime/Logistics support assistant with safety/eval layer
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]>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
//! 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()
|
||||
}
|
||||
Reference in New Issue
Block a user