Skip to main content
Go to documentation:
⌘U
Weaviate Database

Develop AI applications using Weaviate's APIs and tools

Deploy

Deploy, configure, and maintain Weaviate Database

Query Agent

Run agentic search over your Weaviate Cloud collections

Weaviate Cloud

Manage and scale Weaviate in the cloud

Engram

Persistent memory for LLM agents and applications

Additional resources

Integrations
Contributor guide
Events & Workshops
Weaviate Academy

Need help?

Weaviate LogoAsk AI Assistant⌘K
Community Forum

Build a Query Agent e-commerce assistant

In this recipe, we will be building a simple e-commerce assistant agent with the Weaviate Query Agent. This agent will have access to a number of Weaviate collections, and will be capable of answering complex queries about brands and clothing items, accessing information from each collection. By the end, we'll wrap the agent in a small reusable class that's ready to plug into a chatbot, CLI, or any larger application.

Weaviate Query Agent flowchart for the Ecommerce example Weaviate Query Agent flowchart for the Ecommerce example

📚 You can read and learn more about this service in our "Introducing the Weaviate Query Agent" blog.

To get started, we've prepared two open datasets, available on Hugging Face. The first step will be walking through how to populate your Weaviate Cloud collections.

  • E-commerce: A dataset that lists clothing items, prices, brands, reviews, etc.
  • Brands: A dataset that lists clothing brands and information about them such as their parent brand, child brands, average customer rating, etc.

💡 New to the Query Agent? Start with the Get Started recipe — it walks through Ask Mode, Search Mode and Suggest Queries at a higher level before diving into this use-case-focused tutorial.

1. Setting up Weaviate & importing data

To use the Weaviate Query Agent, first, create a Weaviate Cloud account👇

  1. Create Serverless Weaviate Cloud account and setup a free Sandbox
  2. Go to 'Embedding' and enable it, by default, this will make it so that we use Snowflake/snowflake-arctic-embed-l-v2.0 as the embedding model
  3. Take note of the WEAVIATE_URL and WEAVIATE_API_KEY to connect to your cluster below

Info: We recommend using Weaviate Embeddings so you do not have to provide any extra keys for external embedding providers.

!pip install "weaviate-client[agents]" datasets
import os
from getpass import getpass

if "WEAVIATE_API_KEY" not in os.environ:
os.environ["WEAVIATE_API_KEY"] = getpass("Weaviate API Key")
if "WEAVIATE_URL" not in os.environ:
os.environ["WEAVIATE_URL"] = getpass("Weaviate URL")
import weaviate
from weaviate.classes.init import Auth

client = weaviate.connect_to_weaviate_cloud(
cluster_url=os.environ.get("WEAVIATE_URL"),
auth_credentials=Auth.api_key(os.environ.get("WEAVIATE_API_KEY")),
)

Prepare the collections

In the following code blocks, we are pulling our demo datasets from Hugging Face and writing them to new collections in our Weaviate Serverless cluster.

❗️ The QueryAgent uses the descriptions of collections and properties to decide which ones to use when solving queries, and to access more information about properties. You can experiment with changing these descriptions, providing more detail, and more. It's good practice to provide property descriptions too. For example, below we make sure that the QueryAgent knows that prices are all in USD, which is information that would otherwise be unavailable.

Ecommerce and Brands collection example data Ecommerce and Brands collection example data

from weaviate.classes.config import Configure, Property, DataType

client.collections.create(
"Brands",
description="A dataset that lists information about clothing brands, their parent companies, average rating and more.",
vector_config=Configure.Vectors.text2vec_weaviate()
)

client.collections.create(
"ECommerce",
description="A dataset that lists clothing items, their brands, prices, and more.",
vector_config=Configure.Vectors.text2vec_weaviate(),
properties=[
Property(name="collection", data_type=DataType.TEXT),
Property(name="category", data_type=DataType.TEXT),
Property(name="tags", data_type=DataType.TEXT_ARRAY),
Property(name="subcategory", data_type=DataType.TEXT),
Property(name="name", data_type=DataType.TEXT),
Property(name="description", data_type=DataType.TEXT),
Property(name="brand", data_type=DataType.TEXT),
Property(name="product_id", data_type=DataType.UUID),
Property(name="colors", data_type=DataType.TEXT_ARRAY),
Property(name="reviews", data_type=DataType.TEXT_ARRAY),
Property(name="image_url", data_type=DataType.TEXT),
Property(name="price", data_type=DataType.NUMBER, description="price of item in USD"),
]
)
from datasets import load_dataset

brands_dataset = load_dataset("weaviate/agents", "query-agent-brands", split="train", streaming=True)
ecommerce_dataset = load_dataset("weaviate/agents", "query-agent-ecommerce", split="train", streaming=True)

brands_collection = client.collections.use("Brands")
ecommerce_collection = client.collections.use("ECommerce")

with brands_collection.batch.dynamic() as batch:
for item in brands_dataset:
batch.add_object(properties=item["properties"])

with ecommerce_collection.batch.dynamic() as batch:
for item in ecommerce_dataset:
batch.add_object(properties=item["properties"])

2. Set up the Query Agent

When setting up the Query Agent, we have to provide it a few things:

  • The client
  • The collections which we want the agent to have access to.
  • (Optionally) A system_prompt that describes how our agent should behave
  • (Optionally) Timeout - which for now defaults to 60s.

Let's start with a simple agent. Here, we're creating an agent that has access to our Brands & ECommerce datasets, and frame it as a helpful shopping assistant via the system prompt.

from weaviate.agents.query import QueryAgent

agent = QueryAgent(
client=client,
collections=["ECommerce", "Brands"],
system_prompt=(
"You are a friendly e-commerce shopping assistant. "
"Help the user find products from the catalog, compare options, and answer questions about brands. "
"Recommend specific items with their names, brands and prices, and explain why they match the user's request."
),
)

3. Run the Query Agent

When we run the agent, it will first make a few decisions, depending on the query:

  1. The agent will decide which collection or collections to look up an answer in.
  2. The agent will also decide whether to perform a regular search query, what filters to use, whether to do an aggregation query, or all of them together!
  3. It will then provide a response, accessible via response.final_answer, response.sources, or by calling response.display() for a rich formatted view.

Ask a question

Let's start with a simple question: "I like the vintage clothes, can you list me some options that are less than $200?"

We can then also inspect how the agent responded, what kind of searches it performed on which collections, whether it has identified if the final answer is missing information or not, as well as the final answer 👇

response = agent.ask("I like the vintage clothes, can you list me some options that are less than $200?")
response.display()
╭─────────────────────────────────────────────── 🔍 Original Query ───────────────────────────────────────────────╮
│                                                                                                                 │
│ I like the vintage clothes, can you list me some options that are less than $200?                               │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────── 📝 Final Answer ────────────────────────────────────────────────╮
│                                                                                                                 │
│ If you are looking for vintage clothing options under $200, here are some great choices:                        │
│                                                                                                                 │
│ 1. Vintage Philosopher Midi Dress - Priced at $125, this dress from Echo & Stitch embraces a classic        │
│ scholarly look with its deep green velvet fabric and antique gold detailing. It's tailored for elegance and is  │
│ ideal for sophisticated occasions.                                                                              │
│                                                                                                                 │
│ 2. Vintage Gale Pleated Dress - This $120 dress from Solemn Chic features deep burgundy pleats and          │
│ vintage-inspired sleeve details, perfect for a timeless scholarly appearance.                                   │
│                                                                                                                 │
│ 3. Retro Groove Flared Pants - For $59, these electric blue flared pants from Vivid Verse bring back the    │
│ playful spirit of the early 2000s with a modern touch.                                                          │
│                                                                                                                 │
│ 4. Vintage Scholar Tote - At $90, this tote from Echo & Stitch combines functionality and elegance, ideal   │
│ for everyday use, especially if you enjoy a scholarly aesthetic.                                                │
│                                                                                                                 │
│ 5. Electric Velvet Trousers - Priced at $60, these neon green velvet trousers from Vivid Verse offer a fun, │
│ throwback vibe to early Y2K fashion.                                                                            │
│                                                                                                                 │
│ 6. Victorian Velvet Jumpsuit - For $120, this jumpsuit from Solemn Chic offers an elegant blend of romance  │
│ and scholarly charm, suited for library visits or cultured gatherings.                                          │
│                                                                                                                 │
│ 7. Vintage Scholar Turtleneck - This $55 turtleneck from Echo & Stitch suits the Dark Academia vibe,        │
│ perfect for layering or wearing alone.                                                                          │
│                                                                                                                 │
│ 8. Vintage Ivy Loafers - These $120 loafers from Solemn Chic offer timeless sophistication, with a deep     │
│ burgundy finish that complements any vintage wardrobe.                                                          │
│                                                                                                                 │
│ These options cater to various preferences, from dresses and jumpsuits to pants and accessories, all capturing  │
│ the vintage essence at an affordable price.                                                                     │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─────────────────────────────────────────── 🔭 Searches Executed 1/1 ────────────────────────────────────────────╮
│                                                                                                                 │
│ QueryResultWithCollectionNormalized(                                                                            │
│     query='vintage clothes',                                                                                    │
│     filters=IntegerPropertyFilter(                                                                              │
│         property_name='price',                                                                                  │
│         operator=<ComparisonOperator.LESS_THAN: '<'>,                                                           │
│         value=200.0                                                                                             │
│     ),                                                                                                          │
│     collection='ECommerce'                                                                                      │
│ )                                                                                                               │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Ask a follow-up question

Customers rarely ask one question and stop — they have a conversation. To give the agent the prior turns, pass a list of ChatMessage objects to .ask() instead of a single string. The agent will then use the full message history as context.

from weaviate.agents.classes import ChatMessage

conversation = [
ChatMessage(role="user", content="I like the vintage clothes, can you list me some options that are less than $200?"),
ChatMessage(role="assistant", content=response.final_answer),
ChatMessage(role="user", content="What about some nice shoes, same budget as before?"),
]

new_response = agent.ask(conversation)
new_response.display()
╭──────────────────────────────────────────────── 📝 Final Answer ────────────────────────────────────────────────╮
│                                                                                                                 │
│ Here are some great shoe options under $200 that you might like:                                                │
│                                                                                                                 │
│ 1. Vintage Noir Loafers - Priced at $125, these loafers are part of the Dark Academia collection by Solemn  │
│ Chic. They come in black and grey, featuring a classic design with a modern twist. Reviews highlight their      │
│ comfort and stylish appearance, making them suitable for both casual and formal settings.                       │
│                                                                                                                 │
│ 2. Parchment Boots - At $145, these boots from Nova Nest's Light Academia collection are noted for their    │
│ elegant ivory leather and classical detail stitching. They are praised for their comfort and versatile style.   │
│                                                                                                                 │
│ 3. Bramble Berry Loafers - These loafers, priced at $75, come in pink and green and are marked by their     │
│ eco-friendly material and countryside aesthetic. Produced by Eko & Stitch, they are loved for their comfort and │
│ sustainability.                                                                                                 │
│                                                                                                                 │
│ 4. Glide Platforms - Available for $90 from the Y2K collection by Vivid Verse, these platform sneakers are  │
│ both comfortable and stylish with a high-shine pink finish.                                                     │
│                                                                                                                 │
│ 5. Sky Shimmer Sneaks - Costing $69, these sneakers are from the Y2K collection by Nova Nest and offer a    │
│ comfortable fit with a touch of sparkle for style.                                                              │
│                                                                                                                 │
│ These selections offer a mix of formal and casual styles, ensuring you can find a perfect pair under your       │
│ budget of $200.                                                                                                 │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Now let's try a question that should require an aggregation. Let's see which brand lists the most shoes.

response = agent.ask("What is the name of the brand that lists the most shoes?")
response.display()
╭──────────────────────────────────────────────── 📝 Final Answer ────────────────────────────────────────────────╮
│                                                                                                                 │
│ The brand that lists the most shoes is Loom & Aura with a total of 118 shoe listings.                           │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────── 📊 Aggregations Run 1/1 ────────────────────────────────────────────╮
│                                                                                                                 │
│ AggregationResultWithCollectionNormalized(                                                                      │
│     groupby_property='brand',                                                                                   │
│     aggregation=IntegerPropertyAggregation(property_name='collection', metrics=<NumericMetrics.COUNT: 'COUNT'>), │
│     filters=None,                                                                                               │
│     collection='ECommerce'                                                                                      │
│ )                                                                                                               │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Search across multiple collections

In some cases, we need to combine the results of searches across multiple collections. From the result above, we can see that "Loom & Aura" lists the most shoes.

Let's imagine a scenario where the user would now want to find out more about this company, as well as the items that they sell.

response = agent.ask(
"Does the brand 'Loom & Aura' have a parent brand or child brands and what countries do they operate from? "
"Also, what's the average price of a item from 'Loom & Aura'?"
)
response.display()
╭──────────────────────────────────────────────── 📝 Final Answer ────────────────────────────────────────────────╮
│                                                                                                                 │
│ Loom & Aura is itself a well-established brand based in Italy and operates as the parent brand to several child │
│ brands. These child brands include 'Loom & Aura Active', 'Loom & Aura Kids', 'Nova Nest', 'Vivid Verse', 'Loom  │
│ Luxe', 'Saffron Sage', 'Stellar Stitch', 'Nova Nectar', 'Canvas Core', and 'Loom Lure'. The countries           │
│ associated with the operations or origins of these child brands include Italy, USA, UK, Spain, South Korea,     │
│ Japan, and some extend beyond Italy as suggested by the presence of these brands in different countries.        │
│                                                                                                                 │
│ The average price of an item from Loom & Aura is approximately $87.11. This reflects the brand's positioning as │
│ offering items of timeless elegance and quality craftsmanship.                                                  │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

You can see in response.display() that the agent issued two searches against the Brands collection (to find the parent/child relationships) plus one aggregation against the ECommerce collection (to compute the average price) — all from a single natural-language call.

4. Wrap the agent as a reusable assistant

So far we've been calling agent.ask() ad hoc and rebuilding the conversation list ourselves. To plug this into a real app, we want a small wrapper that:

  • Keeps a running conversation history across calls.
  • Returns just the final answer to the caller.
  • Lets us reset between sessions.
from weaviate.agents.classes import ChatMessage

class ECommerceAssistant:
def __init__(self, agent: QueryAgent):
self.agent = agent
self.history: list[ChatMessage] = []

def chat(self, user_message: str) -> str:
self.history.append(ChatMessage(role="user", content=user_message))
response = self.agent.ask(self.history)
self.history.append(ChatMessage(role="assistant", content=response.final_answer))
return response.final_answer

def reset(self):
self.history = []

We can now drive a multi-turn session with a single object:

assistant = ECommerceAssistant(agent)

print(assistant.chat("I like the vintage clothes, can you list me some options that are less than $200?"))
print(assistant.chat("What about some nice shoes, same budget as before?"))
print(assistant.chat("Tell me more about the brand that makes the first pair you mentioned."))

From here, the ECommerceAssistant is a self-contained component you can drop into a web app, Slack bot, CLI, or any flow where a customer needs to talk to your catalog in natural language. Because all of the search and aggregation work is delegated to the Query Agent, your application code stays small.

Extending the assistant

A few directions you can take this from here:

  • Switch to Search Mode for product grids. When you want to render a list of products rather than a written answer, call agent.search(...) and pass response.search_results.objects to your UI. See the Search Mode page.
  • Tune the assistant's voice with a richer system prompt. Add brand-voice guidelines, response formatting (markdown, JSON), or language requirements. See Customizing the System Prompt.
  • Restrict to a single user's data. If your catalog is multi-tenant, set tenant on a QueryAgentCollectionConfig. To enforce a hard filter (e.g. region = "EU") regardless of what the LLM decides, use additional_filters. See Additional Filters and Collection Configuration.

Further resources

  • Build a Streaming Chat UI with Streamlit — A direct continuation of this recipe: wrap the same ECommerce + Brands agent in a Streamlit app with token-by-token streaming, live progress updates, and persisted multi-turn history.
  • Ask Mode — Streaming, system prompts, result evaluation.
  • Multi-turn Conversations — More detail on the conversation pattern used above.
  • Search Mode — Use Search Mode if you want raw results instead of a written answer (for example to render a product grid).

Close the client when you're done:

client.close()