AI agents hallucinate prices: LLM grounding with live data In tests on 21 live product pages from Amazon, Walmart, Best Buy, Target and four Shopify stores, GPT-6 Luna and Claude Opus 5.5 each returned the exact live price for only 2 of 15 products when answering from memory, with median errors of 12% and 17% respectively, according to an Apify analysis. Adding built-in web search raised the exact-match rate but every run still contained wrong prices, each carrying a source link, and a request from outside the US returned an Amazon page in Indian rupees (INR 7,503.02 for an Instant Pot that cost $79 in the US). Apify's proposed fix is a grounded Python agent that pulls live prices from its E-commerce Scraping Tool Actor and lets code, not the model, write each price into the answer, with an explicit failure status when a check fails. Ask an AI agent with no tools what a Kindle Paperwhite costs, and it can answer $159.99, the old launch price. The live price at the time of testing was $199.99. In tests, GPT-6 Luna and Claude Opus 5.5 each matched the live price exactly for 2 of 15 products from memory. With built-in web search, they gave more exact prices, but every run still had wrong prices, each with a source link. Large language model LLM grounding is the standard way to stop both kinds of wrong price, from memory and from web search. A grounded agent answers only from data that it fetched for the question, and every answer shows where that data came from. For prices, a grounded agent needs live data, a clear status when a check fails, and code, not the model, that writes each price into the answer. The Python agent below has each of these. It gets live prices from E-commerce Scraping Tool https://apify.com/apify/e-commerce-scraping-tool , a ready-to-run tool on the Apify marketplace. Apify calls these tools Actors. First, the tests show where wrong prices come from. Then you build the agent and test it step by step. Why AI agents hallucinate prices If your agent shows prices, a wrong one can reach your user in 3 main ways. The model answers from memory, it reads a bad page, or a tool says "ok" when it failed. The tests below check the first 2, on 21 live product pages from Amazon, Walmart, Best Buy, Target, and 4 Shopify stores. A research study tests the third. The live prices come from E-commerce Scraping Tool, and an independent check with a separate scraping service, from US IP addresses, matched the Actor on all 21 pages. The results include only the 15 products with a single clear price for a new item, as a US shopper sees it without member discounts or coupons. A price is exact only when it matches the live price to the cent. The other 6 pages showed no price, or an unclear seller or size. The 15 prices didn't change while the models answered. From memory An LLM learns prices during training, and many of those prices change before a user asks. With no tools, gpt-6-luna and Claude Opus 5.5 gave these results. The last row adds the prompt "If you cannot know the current price, answer UNKNOWN": | Result | gpt‑6‑luna | Claude Opus 5.5 | |---|---|---| | Answers that included a price | 20 of 21 | 21 of 21 | | Exact prices | 2 of 15 | 2 of 15 | | Median error | 12% | 17% | | Prices given for products whose store page showed no price | 2 of 3 | 3 of 3 | | UNKNOWN answers with that prompt | 21 of 21 | 21 of 21 | Without the UNKNOWN prompt, Claude Opus 5.5 added a clear warning, such as "I can't check live prices," to all 21 answers. Each answer still included a price, and agent code reads the number, not the warning. So a prompt alone gave the user either a guess or nothing. Prices can also change fast. The AirPods Pro 3 at Best Buy went from $199.99 to $249.99 in the 3 days before the models were asked. Even a price from last week can mislead your user. From a bad page When your agent fetches pages itself, the page can be the wrong one, even when it loads normally. - Wrong country. A request from outside the US received an Amazon page in Indian rupees. The model read it correctly and answered INR 7,503.02 for an Instant Pot that cost $79 in the US. - Wrong seller. An Amazon page showed "No featured offers available." The model answered $71.89. That price came from the line "Other sellers on Amazon New & Used 2 from $71.89," not from the Buy Box, the main offer on an Amazon page. - Wrong variant. Target redirected the link for the black Kindle Paperwhite to its parent product page, and Owala redirected its FreeSip link to the 32 oz size. A price from the new page can belong to another variant. Code can detect each of these cases, because the data shows the currency, the seller, and the final page URL. From a tool that says "ok" when it failed The preprint Fabrication after tool failure https://arxiv.org/abs/2609.14758 , a study shared before peer review, tested what models do when a tool returns bad data. When the tool returned "ok" with bad data, such as an empty, outdated, or incomplete result, up to 45.3% of answers were dishonest. A dishonest answer hid the failure. When the tool returned an error status instead, the study reported 0% dishonest answers. So a price tool that reports a clear status or error helps the agent give honest answers. What the 3 causes have in common In all 3 causes, the wrong price looks like a normal answer, and nothing tells the user that something failed. The scraper tests show this. In 3 test runs, a simple do-it-yourself DIY scraper received 26 block pages. A block page is what a store shows when it blocks a request, such as Walmart's "Robot or human?" page or Amazon's "Continue shopping" page. The model answered "no price" for all 26. Those answers were honest, but the user still got no price. Every clearly wrong price in these tests came from a page that looked normal. So live data alone isn't enough. The agent also needs a clear status for every price, so that code can flag a wrong page even when it looks normal. Built-in web search adds live data, but it doesn't give a clear status or code that writes each price into the answer. Way 1: price extraction without Apify Agent builders usually start with one of two options: the model's built-in web search or a scraper they write themselves. With the model's built-in web search The model provider runs the search, and your code only enables 1 setting. In this setup, each model answered 3 times for each of the same 15 products: | Result across 3 runs | gpt‑6‑luna | Claude Opus 5.5 | |---|---|---| | Exact prices | 9 to 11 of 15 | 7 to 9 of 15 | | Wrong prices | 4 to 5 of 15 | 5 to 8 of 15 | | No price | 0 to 1 of 15 | 0 to 1 of 15 | | Biggest price error in a run | 25% to 50% | 25% to 30% | Web search gave many more exact prices than memory, but every wrong price included a source link. Those links went to price tracker sites, store search pages, and pages for other products. This was the answer from Claude Opus 5.5 for the Dyson V15 Detect at Best Buy, where the live price was $899.99: {"price": 629.99, "currency": "USD", "source url": "https://www.bestbuy.com/product/dyson-v15-detect-extra-cordless-vacuum-with-10-accessories-yellow-nickel/J3ZCSY279C"} The link opens a different product, the V15 Detect Extra. If your agent uses web search for prices, a wrong price looks the same as a correct one, because each answer cites a source. With your own scraper The DIY scraper fetched each product page and read the schema.org offers object, which many stores add to the page as JSON-LD structured data for search engines . When a page had no JSON-LD price, gpt-6-luna read the page text instead. The same scraper ran from a US cloud server and from a computer outside the US, with 2 HTTP clients. httpx is a standard Python client, and curl cffi copies the TLS fingerprint of a real Chrome browser. The last row shows the better of the 2 clients for each location: | Store | From a US cloud server | From outside the US | |---|---|---| | Amazon 5 pages | Mostly the "Continue shopping" block page | Pages in rupees, or the block page | | Walmart 3 pages | "Robot or human?" with both clients | Product pages with httpx , "Robot or human?" with curl cffi | | Best Buy 5 pages | Timeouts and dropped connections | Timeouts with httpx , prices with curl cffi | | Target 4 pages | Pages loaded, but the price wasn't in the HTML | Pages loaded, but the price wasn't in the HTML | | Shopify stores 4 pages | Prices for Ridge and Allbirds | Prices for Allbirds, and for Ridge with curl cffi | | Exact prices | 3 of 15 | 6 of 15 | These are 2 of the pages that the DIY scraper received: Patchright is an open-source version of Playwright that hides browser automation. With Patchright and Chrome, the scraper got the exact price for 7 of 15 products from outside the US. Walmart still showed the "Robot or human?" page, and Amazon and most Target pages showed no US price. All these results come from basic scrapers with no proxies. A production scraper needs US residential proxies and code for each store, which means more cost and maintenance for your team. Experienced scraper builders often try other sources before a browser. These include the site's internal API, the /products/