Real World Example

ShopEase Policy Assistant with Claude and Chroma

This is the core of support bots at banks (HDFC EVA, SBI SIA), telecoms and e-commerce: answer from policy documents, cite them, and hand over to a human when unsure.

import anthropic, chromadb, voyageai

claude = anthropic.Anthropic()
vo = voyageai.Client()
policies = chromadb.PersistentClient(path="./chroma_db").get_collection("shopease_policies")

SYSTEM = """You are the ShopEase support assistant.
Answer ONLY from the documents provided. Cite document ids like [refunds-2] after each fact.
If the documents do not answer the question, say "I'm not sure about that" and offer a human agent.
Keep answers under 80 words."""

def answer(question: str) -> str:
    qv = vo.embed([question], model="voyage-3.5", input_type="query").embeddings[0]
    res = policies.query(query_embeddings=[qv], n_results=4)
    ids, docs, dists = res["ids"][0], res["documents"][0], res["distances"][0]
    docs_xml = "\n".join(f'<document id="{i}">{d}</document>'
                         for i, d, dist in zip(ids, docs, dists) if dist < 0.6)
    if not docs_xml:
        return "I'm not sure about that. Shall I connect you to a support agent?"
    r = claude.messages.create(
        model="claude-sonnet-5-5",
        max_tokens=400,
        system=SYSTEM,
        messages=[{"role": "user", "content": f"<documents>\n{docs_xml}\n</documents>\n\n<question>{question}</question>"}],
    )
    return next(b.text for b in r.content if b.type == "text")

print(answer("I paid by COD and returned the shoes. Where will my money come?"))

Run it

python policy_bot.py

Example output

Since you paid by Cash on Delivery, your refund will go to your bank account or ShopEase wallet, whichever you choose [refunds-2]. It reaches you within 5-7 working days after the return pickup is completed [refunds-1].

Exercise

Exercise: The bot sometimes answers from only one chunk when two documents disagree (an old and a new policy). How would you fix this in the data and in the prompt?

Show answer
Data:   store "effective_date" and "active" as metadata; filter out
        superseded policies when querying (where={"active": True}).
Prompt: include the date in each <document> tag and add the rule
        "If documents conflict, use the one with the latest effective_date
         and mention the change."