Add Maritime/Logistics support assistant with safety/eval layer #1
@@ -14,18 +14,42 @@ trade-offs documented in [`docs/SAFETY_WRITEUP.md`](docs/SAFETY_WRITEUP.md).
|
|||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
Three narrow agents behind a deterministic supervisor -- the supervisor is
|
Three narrow agents behind a deterministic supervisor:
|
||||||
plain Rust control flow, not another LLM call, so *what's allowed through*
|
|
||||||
is never itself something the model can be talked out of:
|
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
Q["Customer Query"] --> PRE{{"Guardrail: Pre-check<br/>regex injection scan"}}
|
||||||
|
PRE -- allow --> RET["Retrieval Agent<br/>vector search + LLM relevance filter"]
|
||||||
|
RET <--> QD[("Qdrant Vector Store<br/>chunked KB docs")]
|
||||||
|
RET --> DRAFT["Drafting Agent<br/>tool-calling loop"]
|
||||||
|
DRAFT -- lookup_shipment --> SHIP[("Shipment Repository")]
|
||||||
|
DRAFT -- escalate_to_human --> ESC[("Escalation Desk")]
|
||||||
|
DRAFT --> POL["Policy-Compliance Agent"]
|
||||||
|
POL --> DOCS[("acceptable_use.md +<br/>tracking_policy.md")]
|
||||||
|
POL --> POST{{"Guardrail: Post-check<br/>PII/injection scan + policy verdict"}}
|
||||||
|
POST -- allow / escalate --> FINAL["Final Answer + Citations -> Customer"]
|
||||||
|
PRE -- block --> FINAL
|
||||||
|
PRE -.-> AUDIT[("Audit Log<br/>JSONL, append-only")]
|
||||||
|
POST -.-> AUDIT
|
||||||
|
|
||||||
|
classDef agent fill:#eef2ff,stroke:#4f46e5,color:#312e81
|
||||||
|
classDef guardrail fill:#fff7ed,stroke:#ea580c,color:#7c2d12
|
||||||
|
classDef store fill:#f1f5f9,stroke:#64748b,color:#334155
|
||||||
|
classDef audit fill:#f0fdf4,stroke:#16a34a,color:#14532d
|
||||||
|
classDef io fill:#f8fafc,stroke:#334155,color:#0f172a
|
||||||
|
|
||||||
|
class RET,DRAFT,POL agent
|
||||||
|
class PRE,POST guardrail
|
||||||
|
class QD,SHIP,ESC,DOCS store
|
||||||
|
class AUDIT audit
|
||||||
|
class Q,FINAL io
|
||||||
```
|
```
|
||||||
query -> guardrail.pre_check (rule-based, blocks prompt injection)
|
|
||||||
-> RetrievalAgent (Qdrant vector search -> LLM relevance filter)
|
The supervisor (`src/agents/supervisor.rs`) is what runs this graph -- plain
|
||||||
-> DraftingAgent (tool-calling: lookup_shipment, escalate_to_human)
|
Rust control flow, not another LLM call, so *what's allowed through* is
|
||||||
-> PolicyAgent (LLM compliance check against acceptable_use.md)
|
never itself something the model can be talked out of. The dashed edges are
|
||||||
-> guardrail.post_check (rule-based PII/injection scan + policy verdict)
|
the audit trail: every guardrail decision is logged, not just the blocked
|
||||||
-> answer, audit record
|
ones.
|
||||||
```
|
|
||||||
|
|
||||||
Every LLM call asks for a schema-validated structured output (via a forced
|
Every LLM call asks for a schema-validated structured output (via a forced
|
||||||
tool-call, see `src/llm/client.rs`) rather than free text -- there's no
|
tool-call, see `src/llm/client.rs`) rather than free text -- there's no
|
||||||
|
|||||||
Reference in New Issue
Block a user