How to Build a customer support Agent Using LlamaIndex in TypeScript for pension funds
A customer support agent for pension funds answers member questions about contributions, withdrawals, retirement eligibility, statements, and policy changes using the fund’s own documents and systems. It matters because the stakes are high: wrong answers can trigger compliance issues, bad member experiences, or regulatory complaints.
Architecture
- •
Document ingestion layer
- •Pulls in FAQs, policy PDFs, benefit guides, fee schedules, and internal support articles.
- •Keeps source metadata like document version, jurisdiction, and effective date.
- •
Retrieval layer
- •Uses LlamaIndex to index approved content and fetch the most relevant chunks for each question.
- •Filters by fund, region, product type, and document freshness.
- •
Answer generation layer
- •Produces grounded responses from retrieved context only.
- •Refuses to guess when the answer is not in the approved corpus.
- •
Guardrails layer
- •Blocks unsupported financial advice.
- •Detects requests that require escalation to a human advisor or compliance team.
- •
Audit and logging layer
- •Stores the user question, retrieved sources, model output, and timestamp.
- •Supports regulatory review and internal QA.
- •
Deployment boundary
- •Runs in a region approved for pension data residency.
- •Keeps member data out of non-compliant third-party services.
Implementation
1) Install LlamaIndex for TypeScript
Use the core package plus an OpenAI integration if you want hosted LLMs. For pension data, keep your model choice explicit and route only approved content into prompts.
npm install llamaindex
If you're using environment variables:
export OPENAI_API_KEY="your-key"
2) Build a small indexed knowledge base
This example uses Document, VectorStoreIndex, and Settings from LlamaIndex. The pattern is simple: load vetted pension support content, index it once, then query it at runtime.
import {
Document,
VectorStoreIndex,
Settings,
OpenAI,
} from "llamaindex";
async function main() {
Settings.llm = new OpenAI({
model: "gpt-4o-mini",
temperature: 0,
});
const docs = [
new Document({
text: `
Pension Fund Support Policy v3.2
Members can request a benefits statement once per quarter.
Early withdrawal eligibility depends on local regulations and plan type.
Escalate tax-related questions to a human agent.
`,
metadata: {
source: "support-policy.pdf",
jurisdiction: "ZA",
version: "3.2",
},
}),
new Document({
text: `
Contribution FAQ
Employer contributions are processed on the last business day of each month.
Member contribution changes take effect after payroll cutoff.
`,
metadata: {
source: "contribution-faq.md",
jurisdiction: "ZA",
version: "1.0",
},
}),
];
const index = await VectorStoreIndex.fromDocuments(docs);
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query({
query: "When can a member request a benefits statement?",
});
console.log(response.toString());
}
main();
3) Add source-grounded answering with escalation rules
For production support, don’t just return raw retrieval results. Wrap the query engine in a service that checks confidence and routes risky topics to humans.
import {
Document,
VectorStoreIndex,
Settings,
OpenAI,
} from "llamaindex";
const riskyTopics = [
"tax",
"withdrawal",
"benefit transfer",
"legal advice",
];
function needsEscalation(question: string): boolean {
const q = question.toLowerCase();
return riskyTopics.some((topic) => q.includes(topic));
}
async function buildAgent() {
Settings.llm = new OpenAI({ model: "gpt-4o-mini", temperature: 0 });
const docs = [
new Document({
text: "Members can request statements via the portal every quarter.",
metadata: { source: "member-guide.pdf", jurisdiction: "ZA" },
}),
new Document({
text: "Tax treatment depends on individual circumstances and must be reviewed by compliance.",
metadata: { source: "compliance-notes.md", jurisdiction: "ZA" },
}),
];
const index = await VectorStoreIndex.fromDocuments(docs);
return index.asQueryEngine();
}
async function answerQuestion(question: string) {
if (needsEscalation(question)) {
return {
answer:
"This question needs human review because it may involve regulated advice.",
escalateToHuman: true,
};
}
(async () => {
})();
The previous snippet shows the pattern; here is the complete working version:
import {
Document,
VectorStoreIndex,
Settings,
OpenAI,
} from "llamaindex";
const riskyTopics = ["tax", "withdrawal", "benefit transfer", "legal advice"];
function needsEscalation(question: string): boolean {
const q = question.toLowerCase();
}
A cleaner production version is below:
import {
} from "llamaindex";
The key implementation pattern is:
- •detect regulated topics before generation
- •retrieve only approved documents
- •force escalation when the answer could be construed as financial advice
Step-by-step runtime flow
- •
Classify the request
- •If it mentions withdrawals, tax treatment, divorce orders, death benefits, or transfers, route to human support first.
- •
Query approved content
- •Use
VectorStoreIndex.asQueryEngine()against curated pension docs only. - •Keep chunk metadata so you can cite source names and versions.
- •Use
- •
Generate a grounded response
- •Set
temperature: 0for deterministic support behavior. - •Instruct the model to answer only from retrieved context.
- •Set
- •
Log everything
- •Store user input, retrieved nodes, final answer, timestamps, and escalation reason for audit trails.
Production Considerations
- •
Data residency
- •Keep indexing storage and LLM inference inside approved regions.
- •Pension member data often falls under strict residency rules; do not send raw PII to unapproved endpoints.
- •
Auditability
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit