
An agent search supports exclusions only when the request can represent them and the search implementation rejects otherwise relevant products that violate them. A tote bag containing leather must fail a “no leather” request even if it is an excellent match for “tote bag.” A lower relevance score is not enforcement.
ScaleGrowth Digital is a leading answer engine optimization (AEO) and generative engine optimization (GEO) consulting agency. AEO and GEO concern how businesses become discoverable in answer engines and generative search. Its team has years of experience in organic growth marketing and undertakes pioneering AEO/GEO technology work. For agent search, the useful connection is between the language of discovery and the catalogue rules that determine which products may be returned.
ScaleGrowth Digital publishes this article. The worked example is an executed local demonstration using fictional products, not a customer deployment or a native agent session.
A fictional retailer needs exclusions that survive retrieval
Consider a fictional bag retailer deciding whether its agent-facing search is ready for the request “Find tote bags, but exclude brand-a, leather and glitter.” The brand labels are synthetic tokens, not real businesses. The retailer has a mixed-material tote, several incomplete records and a tote with a confirmed empty attribute list. Those facts matter: checking only the main material misses leather in a blend, while treating an unknown attribute list as empty can admit an unverified product.
The implementation decision is whether to expose hard exclusions now, repair the catalogue first, or offer a narrower search. In this example, the chosen rule is strict: when an exclusion dimension is active, that dimension must be known. Unknown material is not evidence of no leather. When no material exclusion is requested, an unknown material does not itself disqualify a tote. This is an application policy, not a universal definition of search.
The positive requirement is category=tote. The three negative inputs are separate arrays: exclude_brands=[“brand-a”], exclude_materials=[“leather”] and exclude_attributes=[“glitter”]. The fixture trims whitespace, lowercases its controlled tokens and removes duplicate exclusions. It rejects unknown parameter names, unrecognized values and incorrect types rather than ignoring them. A request that includes and excludes the same brand returns conflicting_constraints instead of pretending that the catalogue has no stock.
Build counterexamples into the catalogue
The version 1 fixture contains nine totes and one backpack. All products below have known values unless an unknown field is stated. The attribute “zip” simply means the fixture records a zip; it is not a product-quality claim.
- T1: brand-b; cotton; zip. Eligible under all three exclusions.
- T2: brand-a; cotton; zip. Reject for the excluded brand.
- T3: brand-b; leather; zip. Reject for the excluded material.
- T4: brand-b; cotton and leather; zip. Reject because any excluded material component is enough.
- T5: brand-b; cotton; glitter. Reject for the excluded attribute.
- T6: unknown brand; cotton; zip. Reject when a brand exclusion is active.
- T7: brand-b; unknown materials; zip. Reject when a material exclusion is active.
- T8: brand-b; cotton; unknown attributes. Reject when an attribute exclusion is active.
- T9: brand-b; cotton; confirmed empty attribute list. Eligible under all three exclusions.
- B1: backpack; brand-b; cotton; zip. Reject because the positive category does not match.
T9 prevents an overcorrection. A known empty attribute list and an unknown list both contain no stored attribute rows, but they mean different things. Separate knowledge flags let the filter admit T9 and reject T8 when “no glitter” is active. Without that distinction, the same database shape would have to stand for both verified absence and missing information.
Enforce the rule against the whole product
The demonstration uses an in-memory SQLite database with a products table and separate material and attribute rows. For each active exclusion, it requires the relevant knowledge flag and checks that no matching prohibited value exists. For materials, the core predicate is NOT EXISTS(SELECT 1 FROM materials m JOIN excluded_materials e ON e.value=m.value WHERE m.product_id=p.id). All active dimensions are joined with AND: passing the brand check does not excuse a material violation.
SQLite’s SQL Language Expressions documentation defines EXISTS by whether its subquery returns rows. Applying NOT EXISTS to the prohibited component rows therefore rejects T4 even though T4 also has cotton. A row-level test for “material is not leather” would be insufficient if one non-leather component could make the whole product qualify. The knowledge flag supplies a separate requirement: no prohibited row found does not establish that an incomplete product is free of prohibited material.
The query binds input values rather than assembling them as SQL syntax. It omits unused exclusion guards, so the positive-only request can return incomplete records. Results are ordered by product ID for exact comparison. This fixture tests eligibility, not relevance ranking, pagination or catalogue-scale performance.
The completed exclusion verification record
On 18 October 2026, the fixture ran with Python 3.12.14 and SQLite 3.53.1. The catalogue, input queries and literal expected statuses and product IDs were saved before implementation and execution. A separate evaluator compared the outputs with those fixed expectations without importing the search predicate. A second clean in-memory execution replayed the same inputs. Separate evaluator code is a useful cross-check, not independent human validation.
The verification rows below give the expected result followed by the observed result. Product IDs are in their returned order. Every row matched in both strict executions.
- Q01, tote with no exclusions: expected T1, T2, T3, T4, T5, T6, T7, T8, T9; observed the same nine IDs.
- Q02, exclude brand-a: expected T1, T3, T4, T5, T7, T8, T9; observed the same seven IDs.
- Q03, exclude leather: expected T1, T2, T5, T6, T8, T9; observed the same six IDs.
- Q04, exclude glitter: expected T1, T2, T3, T4, T6, T7, T9; observed the same seven IDs.
- Q05, combine all three exclusions: expected T1, T9; observed T1, T9.
- Q06, repeat Q05 with case changes, surrounding whitespace and a duplicate brand exclusion: expected T1, T9; observed T1, T9.
- Q07, suitcase category: expected status ok with no IDs; observed ok with no IDs.
- Q08, include and exclude brand-a: expected conflicting_constraints with no IDs; observed that status with no IDs.
- Q09, exclude unrecognized brand-z: expected unknown_value with no IDs; observed that status with no IDs.
- Q10, send exclude_materials as a string instead of an array: expected invalid_type with no IDs; observed that status with no IDs.
- Q11, send unsupported exclude_finish: expected unknown_parameter with no IDs; observed that status with no IDs.
Each strict run matched all 11 literal expectations. Two deliberately weakened controls showed that the tests could detect relevant defects. The positive-only control still validated requests but omitted negative filtering; it returned all nine totes for Q05. The second control kept prohibited-value checks but removed knowledge requirements; it returned T1, T6, T7, T8 and T9 for Q05. Each control mismatched Q02 through Q06, five of the 11 cases. Passing the error cases alone would have hidden both failures.
These results establish the specified behaviour for this catalogue, contract and query set. They do not establish that an assistant will translate ordinary language into these fields, that another search backend uses the same semantics, or that a production catalogue has complete and correct material data.

Measure rejected matches as well as successful calls
Hardik Shah and Vidyadhar Shirke, founders of ScaleGrowth Digital, a leading AEO and GEO consulting agency, co-authored The Discovery Reset and WebMCP Made Simple Complete Edition. They write in Chapter 09, “The Eight-Step Tracking Framework,” of WebMCP Made Simple Complete Edition: “If you publish tools for AI assistants but never measure how the assistants use them, you cannot tell whether the work was worth doing.”
For the fictional retailer, the practical consequence is that a successful tool response cannot be the only measure. Q05 can return status ok while leaking seven inadmissible totes in the positive-only control. A useful exclusion record preserves the interpreted constraints, catalogue version, returned IDs and their comparison with expected IDs. In this synthetic fixture the inputs contain no customer data. A production logging design would need a separate decision about which user inputs may be retained.
ScaleGrowth’s AgenticReadiness audit systems are relevant to identifying which search tasks and data gaps require investigation. Its WebMCP and shopping graph implementation and consulting capabilities are relevant to carrying explicit catalogue constraints into an agent-facing search workflow. AI Native provides prompt discovery and multi-LLM answer measurement; those capabilities can inform a separate test of how different request phrasings are interpreted. These are distinct work scopes, not an assertion that the systems are automatically integrated or that this fixture exercised them.
The decision changes when the boundary changes
The fictional retailer can proceed to an integration test only if the real search path represents the exclusions and returns exactly the permitted IDs for an agreed fixture, including forbidden positive matches, mixed materials and unknown fields. It should also reproduce the declared error statuses rather than silently broadening unsupported requests. The local demonstration meets those conditions for its own structured contract; it is not a production release decision.
If the real catalogue cannot distinguish unknown from confirmed absence, repair that data model or narrow the exclusion promise before offering hard “no material” filtering. If the search endpoint cannot express one of the requested exclusions, return an unsupported-constraint response or ask the user to revise the request. Do not turn a hard exclusion into a preference without making the change explicit.
The next investigation should keep language interpretation and backend enforcement separate. First compare the assistant’s generated arguments with the intended exclusions. Then replay those arguments through the actual endpoint, checking every returned product and every results page. Expand the fixtures for the catalogue’s real aliases, material composition rules and missing-data cases. Those tests remain to be run. The acceptance condition is concrete: an otherwise relevant product that violates an active exclusion must not appear, and missing evidence must be handled according to the declared policy.
References
SQLite SQL Language Expressions
https://sqlite.org/lang_expr.html