~/bpabatao
← back to index
~/case/ccs-kb

CCS Knowledge Base Agent

A retrieval agent over utility billing systems that answers from curated documentation first and only reaches for generated SQL behind a flag.

Role
Sole author
Period
2026
Ownership
Sole author
Stack
AWS Bedrock · RetrieveAndGenerate · Fargate · S3 · Oracle CCS · TypeScript
questionkb agentanswercited + badgedcurated corpusretrieve + generatedefault pathgenerated sqlflag + permissionoff by defaults3 corpusscheduled refreshoracle ccstenant-scopednever claims absence

Problem

Answering a question about a utility account meant knowing which of several tenant systems held the answer, which schema it used, and which of its account types applied. That knowledge lived with a handful of people, and the questions arrived constantly.

A language model over the data is the obvious idea and the dangerous one. On billing records the failure mode is not a bad sentence, it is a confident wrong number, or a claim that something does not exist when the query simply missed it.

Constraints

The corpus describes real customers, including person identifiers such as SSN fields, so the schema had to be modelled explicitly rather than left for the model to infer. Tenants must never see each other's data, and an answer that cannot be grounded has to say so instead of guessing.

Architecture

Curated first. Questions route through Bedrock's RetrieveAndGenerate over a curated corpus - an account-type catalog covering collective, secondary, usage, registration and service states - and answers cite the source they came from, with a badge marking whether that source is authoritative for the environment being asked about.

Generated SQL is the fallback, not the default. It sits behind an environment flag and a separate grantable permission, so a deployment can run the agent with the SQL path entirely off. A source selector lets the asker choose documentation, live data, or automatic.

The guardrails are the product. The prompt forbids claiming absence - the model may not say a thing does not exist merely because a lookup returned nothing - and is guarded against inventing terms, confusing environments, or mislabelling a count column. Tenant routing is explicit, scoped per tenant family, so a question can only reach the data it is entitled to.

The corpus does not go stale: a scheduled Fargate task refreshes it, with the task role scoped to exactly the S3 and Bedrock actions that refresh needs.

Outcome

← all projects