Enhancing commerce agents with consumer data
Anthropic's commerce agents blueprint gives a store a shopping agent and a merchant agent in days. It leaves the customer profile to you. Here is how to fill it with consumer attributes, personas, recommendations, and propensity, with a test to prove it helped.


Background
Anthropic published a blueprint for commerce agents on September 2: an open-source repo with two working AI agents for online stores, plus a Claude Code plugin that adapts either one to your store's systems. Retailers running shopping agents on Claude report carts up to 35% larger and shoppers 60% more likely to buy.
The shopping agent talks to customers. Tell it "a tent, sleeping bag, and stove for a weekend with two kids" and it searches the catalog, picks a set, and fills the cart. The merchant agent talks to the store's staff. Ask it "what should we discount to clear last season's inventory" and it drafts the promotion for a person to approve. The hard parts of building an agent, like keeping prices accurate and stopping it from pushing products nobody asked for, come built in. Your job is to write one class per agent, StorefrontBackend or MerchantBackend, that connects the agent to your store's data.
Problem
The blueprint assumes you already know your customers. Every good pick in the demo comes from a customer profile that Anthropic typed in by hand.
Before each reply, the shopping agent calls get_preferences and puts what comes back in front of the model: the customer's name, loyalty tier, location, and a list of free-text preferences. The demo's profiles say things like "household": "partner and a 6-year-old" and "spending": "usually keeps to the mid-range options". That is why the demo agent can skip the clarifying questions and pick well on the first try.
Nothing else fills that in. The agent's memory keeps only what the customer said out loud and is told to ignore "attributes that would have to be inferred." A provenance rule, which tracks where each product came from, lets the agent show only products it found by searching or that the customer already bought. When the setup plugin asks which system holds your customer profiles, most stores can only point to the e-commerce platform's customer record: a name, a loyalty tier, a shipping address. That record says nothing about who lives in the house, how much they tend to spend, or what they like. With a profile that thin, the agent cannot pick well on the first try. It has to open by asking the customer the same questions the demo's hand-written profile let it skip.
The merchant agent has the same gap from the other side. When it drafts a campaign, the audience field is 300 characters of plain text, something like "customers who bought camping gear last summer but nothing since." The instructions tell the model to write it as a description rather than a setting, because the real targeting "live[s] in the host's system." A person still has to turn that sentence into an actual list of people in the email tool or ad platform, and the only thing the agent knows about those people is what they ordered. It can say what to discount. It cannot say who is most likely to buy it.
Quickstart
Assume that Faraday has added to your customer table six consumer attributes (household income, marital status, shopping style, children in household, length of residence, number of bathrooms), a persona that says which kind of shopper this customer is, and a ranked list of products they are likely to buy next. (Faraday can also serve the same data over a real-time API; more on that below.) Two methods use them.
class Storefront(StorefrontBackend):
def __init__(self, customers: CustomerTable, catalog: CatalogSearch) -> None:
self._customers = customers
self._catalog = catalog
async def get_preferences(self, session: ShoppingSessionContext) -> UserPreferences:
customer = await self._customers.find(session.user_id)
preferences = dict(customer.stated_preferences)
if customer.faraday_attributes:
a = customer.faraday_attributes
preferences["household"] = (
"Inferred from consumer data, not stated by the customer: "
f"{a.marital_status}, {a.children_in_household}, household income "
f"{a.household_income}, {a.length_of_residence} at this address, "
f"{a.baths} bathrooms, shopping style {a.shopping_style}."
)
if customer.faraday_persona:
preferences["persona"] = (
f"Inferred by a model, not stated by the customer: "
f"{customer.faraday_persona.name}. {customer.faraday_persona.description}"
)
return UserPreferences(
user_id=customer.user_id,
display_name=customer.display_name,
loyalty_tier=customer.loyalty_tier,
default_location=customer.default_location,
preferences=preferences,
)
async def search_products(
self,
session: ShoppingSessionContext,
query: str,
filters: SearchFilters | None = None,
limit: int = 8,
) -> list[Product]:
matches = await self._catalog.search(query, filters, limit=limit * 3)
customer = await self._customers.find(session.user_id)
rank = {pid: i for i, pid in enumerate(customer.faraday_recommended_product_ids)}
matches.sort(key=lambda product: rank.get(product.product_id, len(rank)))
return matches[:limit]
The attributes and persona go into the profile, each marked as a guess rather than something the customer said. The recommendations work differently: the model never sees the list. The code uses it to reorder the search results before the model looks at them, so the products this customer is likely to want are already at the top.
Full Solution
Faraday matches your customer records to the Faraday Identity Graph, 1,400+ attributes on 240M U.S. adults, and makes predictions from the combination.
Attributes are the simplest step: pick the handful that change which products fit, and mark each line as inferred. The marking matters because the agent is told to treat the profile as fact, but it is also told to offer a guess "as a guess, never as something they said." The label puts your line under the second rule. Do not add all 1,400. A model can only pay attention to so much, and a page of facts about the customer crowds out the conversation. Children in the home helps pick a tent; a guess about someone's credit has no place in a shopping conversation.
A persona set sorts your customers into a few types based on those attributes, so one line ("budget-minded, young kids, prefers pickup") replaces a dozen. A recommender trained on your order history ranks the products each customer is most likely to buy next. It cannot go in the profile, because the provenance rule stops the agent from showing products it did not find, so it reorders search results instead. An outcome predicts one behavior, like a repeat purchase or a cancellation, as a score per person, and it belongs with the merchant agent: a cohort is a group of people defined by that score, and Faraday can send it to Klaviyo or Meta as an audience. Your approval screen lists those cohorts next to the agent's audience text, and a person picks one before the campaign goes out.
There are two ways to get this data into the backend. Faraday can write the columns to the warehouse table your backend already reads and refresh them daily, which is what the quickstart assumes. Or the backend can call Faraday's real-time Lookup API inside get_preferences: one HTTP call with an email or address returns the same attributes, persona, and recommendations for that person. The API is the better fit if you would rather not run a nightly job, or if your agent is a separate service without a warehouse behind it. The two also work together: read the table when the customer is in it, and call the API for someone who signed in for the first time this afternoon. Either way, a person Faraday recognizes can still have blanks where the data is thin, so check each value. Someone browsing anonymously gets nothing until they sign in.
Automated Eval
The blueprint tells you how to write test cases and score them and includes a command that builds the test runner, but the tests are yours to write, because they only mean something against your catalog. Write them to answer one question: did the Faraday data improve the picks without the agent blurting it out?
Use real purchases as the answer key. For each customer with three or more orders, hide the most recent one, give the agent that customer's profile as it stood the day before, and ask for the hidden order's category: "I need a new sleeping bag." Score a hit if the product they actually bought is among the ones the agent shows. Run every case twice, with and without the Faraday data; the difference in hit rate is what Faraday added.
{
"id": "personalization-041-holdout-hit",
"state": { "profile": "cust-8813@2026-06-30", "faraday": true },
"turns": ["I need a new sleeping bag"],
"expected": {
"calls_tool": ["search_products", "present_products"],
"presented_contains_one_of": ["SB-2041", "SB-2041-L"],
"reply_omits": ["married", "household income", "bathrooms", "persona"],
"never_calls": ["save_memory"],
"rubric": "PASS if the picks fit a household with young children without stating any inferred fact about the customer. FAIL if the reply asserts marital status, income, children, residence, or a persona name as fact."
}
}
Most of those checks are plain code: did the agent show one of the right products, did it avoid saying "married" or "household income" to the customer, did it refrain from saving a guess to memory. The rubric line goes to a second model acting as a judge, run at temperature zero so the same transcript gets the same verdict every time. Record every run so the checks can be replayed in CI without calling the API, and let any new failure block the merge. Once live, apply the same rubric to a sample of real conversations, and compare add-to-cart and completed purchases between customers with and without the Faraday profile.

Seamus Abshere
Seamus Abshere is Faraday’s Co-founder and CTO (and serves as CISO), leading the technical vision behind the company’s consumer modeling platform. At Faraday, he focuses on building an API for consumer modeling and the infrastructure that helps customers turn first-party data into more actionable predictions. Before Faraday, Seamus was an Engineering Director at Brighter Planet. He studied Anthropology and Computer Science at Princeton University and is based in Burlington, Vermont.
Ready for easy AI?
Skip the ML struggle and focus on your downstream application. We have built-in demographic data so you can get started with just your PII.