← Back to documentation

ml-practitioner-post

Using BuyWhere as a Data Source for LangChain Shopping Agents

By Draft · April 2026

Building AI agents that help users shop requires reliable product data. BuyWhere's agent-native API is designed exactly for this use case — giving your LangChain tools real-time price comparison, availability checking, and multi-retailer coverage.

In this post, we'll build a working shopping agent loop using BuyWhere as a tool within LangChain.

Why BuyWhere for AI Agents?

Traditional e-commerce APIs return static product listings. BuyWhere gives you:

  • Real-time price comparison across 20+ Singapore retailers
  • Natural language search optimized for agent queries
  • Batch lookups so your agent can compare multiple products efficiently
  • Multi-currency support for SEA market expansion

LangChain Tool Wrapper

from langchain.tools import Tool
from langchain.agents import initialize_agent, AgentType
import requests

BUYWHERE_API_KEY = "your_api_key"
BASE_URL = "https://api.buywhere.ai/v1"

def search_products(query: str, limit: int = 10) -> str:
    """Search for products by name or description."""
    url = f"{BASE_URL}/agents/search"
    headers = {"Authorization": f"Bearer {BUYWHERE_API_KEY}"}
    params = {"q": query, "limit": limit}
    resp = requests.get(url, headers=headers, params=params)
    resp.raise_for_status()
    data = resp.json()
    
    if not data.get("results"):
        return "No products found."
    
    results = []
    for p in data["results"][:5]:
        results.append(
            f"- {p['title']}: ${p['price']} {p['currency']} "
            f"at {p['source']} ({'in stock' if p.get('is_available') else 'out of stock'})"
        )
    return "\n".join(results) if results else "No results found."

def compare_prices(product_name: str) -> str:
    """Compare prices for a specific product across all retailers."""
    url = f"{BASE_URL}/agents/price-comparison"
    headers = {"Authorization": f"Bearer {BUYWHERE_API_KEY}"}
    params = {"product_name": product_name}
    resp = requests.get(url, headers=headers, params=params)
    resp.raise_for_status()
    data = resp.json()
    
    if not data.get("results"):
        return f"No price data found for '{product_name}'."
    
    lines = [f"Price comparison for '{product_name}':\n"]
    for item in data["results"][:10]:
        lines.append(
            f"- {item['source']}: ${item['price']} {item['currency']} "
            f"(rank #{item['price_rank']})"
        )
    
    if data.get("best_deal"):
        bd = data["best_deal"]
        lines.append(f"\n**Best deal**: {bd['source']} at ${bd['price']} {bd['currency']}")
    
    return "\n".join(lines)

# LangChain tools
search_tool = Tool(
    name="product_search",
    func=search_products,
    description="Search for products by query. Use when user wants to find products."
)

compare_tool = Tool(
    name="price_compare",
    func=compare_prices,
    description="Compare prices for a specific product across retailers."
)

tools = [search_tool, compare_tool]

A Worked Shopping Agent Loop

from langchain.agents import initialize_agent, AgentType
from langchain.llms import OpenAI
import os

os.environ["OPENAI_API_KEY"] = "your_openai_key"

llm = OpenAI(temperature=0)
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# Example conversation
agent.run(
    "Find me a good wireless headphone under $100. "
    "Compare prices across retailers and recommend the best value option."
)

Agent thought process:

Thought: The user wants wireless headphones under $100. 
I should first search for wireless headphones to see what's available.
Action: product_search
Action Input: "wireless headphones"
Observation: Found 15 products. Let me narrow down by price.
...
Thought: I found several options. Now I should compare prices
to find the best deal under $100.
Action: price_compare
Action Input: "Sony WH-1000XM5"
Observation: Best deal at Shopee: $89.00 SGD - $10 below average.
Final Answer: The Sony WH-1000XM5 at Shopee for $89.00 SGD 
is the best value wireless headphone under $100.

Batching vs Streaming: Tips

For Batch Processing (Recommended)

When your agent needs to evaluate many options, use batch lookups:

def batch_lookup(product_ids: list[int]) -> dict:
    """Look up multiple products by ID in a single request."""
    url = f"{BASE_URL}/agents/batch-lookup"
    headers = {"Authorization": f"Bearer {BUYWHERE_API_KEY}"}
    payload = {"product_ids": product_ids}
    resp = requests.post(url, headers=headers, json=payload)
    return resp.json()

# Agent evaluates 5 options at once
options = batch_lookup([12345, 67890, 11111, 22222, 33333])

For Streaming (Real-time UX)

For live shopping experiences where users expect instant results:

import asyncio

async def stream_search(query: str):
    async with httpx.AsyncClient() as client:
        url = f"{BASE_URL}/agents/search"
        headers = {"Authorization": f"Bearer {BUYWHERE_API_KEY}"}
        params = {"q": query, "limit": 5}
        
        async with client.stream("GET", url, headers=headers, params=params) as response:
            async for line in response.aiter_lines():
                if line.startswith("data:"):
                    yield json.loads(line[5:])

MCP Integration

For Model Context Protocol (MCP) integration, see the BuyWhere MCP documentation. Note: MCP endpoints require server-side configuration — consult the documentation for setup instructions.

What's Next?

Start building your shopping agent today!