Inspiration
Most "AI agents" are frozen the moment you ship them — as good on day 300 as on day one. That always bothered us, so we set out to build the opposite: an agent whose value accrues with use. We called it Patina — because, like the patina on bronze, it should get richer and more valuable the more that passes through it.
We picked a deliberately unglamorous domain: vendor onboarding. Before a company can pay a new supplier, someone reads a messy document packet — business registration, bank letter, insurance certificate — extracts every field, cross-checks consistency, applies policy, and flags the genuine problems. It's slow, repetitive, and a static tool never gets better at it. Perfect for an agent — but only if the agent stops asking the same human the same question twice.
What it does
Patina onboards a supplier's document packet end-to-end: it reads each document with Qwen-VL into structured fields with per-field confidence, validates them against policy (bank holder vs registered entity, expiry dates, coverage), and routes only genuine, novel exceptions to a human — each with reasoning and a memory-backed "here's how we handled this last time." Then it remembers how each case was resolved, so it gets measurably better every time.
Three demo scenarios show the compounding, with human-touches falling to zero:
- Format memory — it flags a novel Chinese 营业执照 layout once; a human confirms; the next Chinese vendor is recognized and auto-approved. The same memory card climbs from 60% to 80% relevance and shows the vendors it has served.
- Exception memory + due diligence — a vendor banks under a trading name that differs from its registered entity. Instead of guessing, the agent investigates: it checks the business registry and screens sanctions, and distinguishes a legitimate trading name (same registration → approve) from a subsidiary (its own registration → escalate for payment authorization). Approve it once, and repeat legitimate mismatches become a quiet note, not a false alarm — it stops crying wolf.
- Decay / invalidation — expired insurance is re-flagged even after prior acceptance, because a separate hard-invalidation layer never lets stale facts be suppressed.
How we built it
The core is a custom-engineered memory layer — not an off-the-shelf memory API and not a vector-store wrapper. It's built on PostgreSQL + pgvector as a single store for relational metadata and embeddings, with four ideas:
- Multi-scoped memory — format, exception, entity, and episodic scopes, each with its own decay rate.
- Hierarchical distillation — resolved cases are compressed into compact structured facts (via
qwen-flash), not transcripts. - Purposeful decay + hard-invalidation — relevance fades on a true half-life curve but resets on usefulness (spaced repetition); expired/superseded facts are retired, not faded.
- Multi-signal hybrid retrieval —
final = 0.5·semantic + 0.3·structured + 0.2·decay, all in one SQL query.
Around it is a staged pipeline with explicit, persisted state — Intake → Extraction → Validation → Memory-Consult → Exception-Route → Human-Gate → Learn — not one mega-prompt. Deterministic Python handles arithmetic and dates; Qwen handles the fuzzy work. Novel exceptions are adjudicated with Qwen native function-calling over custom tools and two MCP servers (a business-registry / denied-party lookup and a memory search).
Models: qwen3.7-plus (multimodal extraction, reasoning, tools), qwen-vl-ocr (hard-OCR fallback), text-embedding-v4 (1024-dim), qwen-flash (distillation) — all via Model Studio / DashScope, Singapore.
Deployment: the full backend runs on Alibaba Cloud Function Compute (custom container) with ApsaraDB RDS PostgreSQL 16 + pgvector; the Next.js + Tailwind dashboard is on Vercel. A /proof endpoint round-trips through Qwen from inside the deployed function to prove live model access.
Challenges we ran into
- Keeping the memory visibly non-trivial. The whole thesis collapses if a judge sees "vector store + RAG." We had to make the multi-scoping, decay, and hybrid retrieval genuinely engineered — and testable (32 tests).
- A subtle recognition bug. In an early run, a Japanese vendor auto-approved when it should have flagged — the learned Chinese format had leaked into the Japanese query, because v1 retrieval scores country only softly. We fixed it by applying the structured country match as a hard gate for format recognition, so the two scripts stay learned separately.
- Decay semantics.
exp(-Δt/halflife)doesn't actually halve at the halflife; we switched to a true half-life curve (2^(-Δt/halflife)) so "halflife = 180 days" means what it says. - Cloud gotchas. Custom-container functions need a service-linked role; a stale image (built before a DB fix) 500'd against RDS until we rebuilt; raw DB passwords with special characters broke URL parsing; and PDF uploads had to be rendered to images before Qwen-VL.
- Distinguishing a trading name from a subsidiary — a real compliance nuance — required resolving the relationship by registration number, not by string similarity.
Accomplishments that we're proud of
- A memory engine that genuinely compounds — you can watch a memory card get created at 60%, then reinforced to 80%, with the list of vendors it has served.
- An evidence-based human-gate: the agent gathers registry + sanctions evidence and recommends a decision, correctly telling a legitimate trading name (approve) from a subsidiary (escalate). That domain depth is what separates a real tool from a demo.
- The full stack live on Alibaba Cloud, calling Qwen, end-to-end — not a proof-of-concept.
- Qwen's CJK vision reading a deliberately warped "phone photo" of a Chinese license perfectly.
What we learned
- Let the model surprise you before you over-engineer. We'd budgeted time to promote a dedicated OCR model to primary; Qwen's CJK vision was so strong we deleted that whole subsystem.
- Make the hard part the interesting part. Renting a memory API would have saved a day and cost us the entire story.
- Instrument the payoff. A counter that falls to zero on screen is worth a thousand architecture slides.
- Decay-plus-reinforcement, distilled facts over transcripts, and a structured gate over pure similarity are the details that make a memory trustworthy.
What's next for Patina
- Deeper memory: confidence-weighted decay (human-confirmed resolutions get a bigger bump, overrides get penalized) and an LLM reranker over the top-k candidates.
- Event-driven intake: OSS object-create triggers so a dropped packet onboards itself; async processing so uploads return instantly.
- Production diligence: wire the adjudicator to real business-registry and sanctions APIs.
- More document types and an org-specific memory that becomes a compounding asset — a knowledge base that's worth more the longer you use it.
Built With
- alibaba-cloud
- apsaradb
- dashscope
- docker
- fastapi
- function-compute
- mcp
- model-studio
- next.js
- pgvector
- postgresql
- pydantic
- python
- qwen
- qwen3.7-plus
- react
- serverless-devs
- tailwindcss
- typescript
- uv
- vercel
Log in or sign up for Devpost to join the conversation.