Compare products on the same criteria, with prices checked
Comparisons from a chat often judge each product on different points and quote prices nobody checked. This workflow fixes the criteria first, researches each product in its own run, checks every price and spec against a source, then makes a pick.
4 steps in 4 stages · 4 subagents · a kit of 9 files
Free. Built in your browser; nothing is uploaded. No API key, no account.
How it runs
Steps in the same stage start at the same time. Each subagent gets only what its incoming edges carry, and a step in a fresh context never sees the reasoning of the steps before it. A gate decides whether the work passes, and a failed gate re-runs the work it checks.
- Stage 1
Shortlist · Planner
sonnet · WebSearch, WebFetch
- Stage 2
Research each product · Worker
sonnet · WebSearch, WebFetch · once per item of shortlist.products
- Stage 3
Check the facts · Checker
opus · WebSearch, WebFetch · fresh context
Gate: Every price and spec has a source, every product is judged on the same criteria, and nothing is claimed that was not found.
- Stage 4
Verdict · Writer
sonnet · WebFetch
Use it when
- You are choosing between products or plans.
- Prices and specs matter to the decision.
- You want the same criteria applied to every option.
Change these first
- Give a budget and the criteria that matter to you.
- Name the products, or let it build the shortlist.
Need a workflow built for your team? Fixed-price packages
What you get
An orchestrating SKILL.md, one Claude Code subagent per step with its own tools and model, and the same skill as a Cursor rule. Your agent runs it with its own subagents; nothing on this site calls a model.
- .claude/skills/compare-products/SKILL.mdorchestrator
- .claude/skills/compare-products/graph.skill.mdgraph source
- .claude/agents/compare-products-shortlist.mdsubagent
- .claude/agents/compare-products-research-product.mdsubagent
- .claude/agents/compare-products-fact-check.mdsubagent
- .claude/agents/compare-products-verdict.mdsubagent
- .skill-graph/.gitignoresupport
- .cursor/rules/compare-products.mdcCursor rule
- README.mdreadme
---
name: compare-products
description: "Compares products or options side by side on the same criteria, researches each one on the web, checks every price and spec, then recommends one."
---
# compare-products
Compares products or options side by side on the same criteria, researches each one on the web, checks every price and spec, then recommends one.
This skill is a graph: each step has its own prompt and context, and only the payloads named below move between steps.
## Plan
Run the stages in order. Every model step runs in its own subagent; do not do a step's work yourself. Only command steps and approvals are yours to run. Steps in the same stage do not depend on each other: start them together, in one message with several subagent calls.
The input (`wish`) is the user's goal: their request, word for word, handed on under `### wish`. Ask for it if the user has not given one.
### Stage 1 · 1 step
- **SHORTLIST** (`shortlist`) → subagent `compare-products-shortlist`
- Hand it: the user's goal.
- Expect: `shortlist_json` (json).
- Contract check (`shortlist_json`): save its output to `.skill-graph/compare-products/shortlist.json`, then run `node -e "const fs=require('fs');const d=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));const k=['products','criteria'];const ok=d!==null&&typeof d==='object'&&Array.isArray(d)===false;const m=ok?k.filter((x)=>Object.hasOwn(d,x)===false):k;if(m.length>0){console.error('Missing keys: '+m.join(', '));process.exit(1)}" .skill-graph/compare-products/shortlist.json` with Bash. Exit code 0 passes.
- If a contract check fails: re-run this step once with its previous answer and the error output. If it fails again, stop and show the user the output.
### Stage 2 · 1 step
- **RESEARCH EACH PRODUCT** (`research_product`) → subagent `compare-products-research-product` · one run per item, up to 4 at a time
- Take the list: the `products` array in the JSON of SHORTLIST (`shortlist`). If it is not an array, stop and report. If it is empty, skip this step: its output is `[]`.
- If the list has more than 6 items, stop before starting any run and tell the user how many there are.
- Start one run of the subagent per item, up to 4 at a time (several subagent calls in one message); start the next as one finishes.
- Hand each run: its item: one entry of `products` from the JSON of SHORTLIST (`shortlist`); the `criteria` value from the JSON of SHORTLIST (`shortlist`).
- Expect, per run: the result for its item. Checks and gates below apply to each run on its own; a retry re-runs only the runs that failed.
- Output: a JSON array of the runs' results, in item order. That array is what later steps get.
### Stage 3 · 1 step
- **CHECK THE FACTS** (`fact_check`) → subagent `compare-products-fact-check` · fresh context
- Hand it: the user's goal; the output of RESEARCH EACH PRODUCT (`research_product`). Nothing else: no notes of your own, no other step's reasoning, no earlier conversation.
- Expect: `checked_notes` (markdown).
… 33 more lines in the kitRun it in a Claude chat
Add Skill Graph to Claude as a connector, then ask. Claude runs each step and the connector checks every answer before the next one starts.
Set up the connectorAsk Claude
Use Skill Graph to run the compare-products workflow on: Compare 3 robot vacuums under $400 for a home with pets.The graph file
The whole workflow is one Markdown file, graph.skill.md: the steps and edges in the frontmatter, one prompt per step below it. The guide explains every field.
graph.skill.md · 105 lines
---
name: compare-products
description: Compares products or options side by side on the same criteria, researches each one on the web, checks every price and spec, then recommends one.
spec: skill-graph/1
topology:
nodes:
- id: wish
type: input
label: WHAT TO COMPARE
- id: shortlist
type: orchestrator
label: SHORTLIST
model: sonnet
tools: [WebSearch, WebFetch]
output_format: json
- id: research_product
type: worker
label: RESEARCH EACH PRODUCT
model: sonnet
tools: [WebSearch, WebFetch]
foreach: shortlist.products
max_items: 6
- id: fact_check
type: verifier
label: CHECK THE FACTS
isolated_context: true
model: opus
tools: [WebSearch, WebFetch]
gate: Every price and spec has a source, every product is judged on the same criteria, and nothing is claimed that was not found.
on_fail: retry
max_retries: 1
- id: verdict
type: synthesizer
label: VERDICT
model: sonnet
tools: [WebFetch]
edges:
- from: wish
to: [shortlist, fact_check, verdict]
- from: shortlist
to: research_product
contract: shortlist_json
- from: research_product
to: fact_check
contract: product_notes
- from: fact_check
to: verdict
contract: checked_notes
contracts:
shortlist_json:
format: json
description: "{ products: the 2 to 5 products to compare, criteria: what to compare them on, budget: the budget or null }"
required: [products, criteria]
product_notes:
format: json
description: One entry per product, in shortlist order; each has its price and a value for every criterion, each with a source.
checked_notes:
format: markdown
description: The checked facts per product, with sources, and what was corrected or could not be found.
---
# Node Prompts & Edge Contracts
## @node: shortlist
Decide what to compare from this request:
{{wish}}
If the request names products, use those. If not, search the web and pick the 3 that fit it best. Choose 4 to 6 criteria that matter for this choice, such as price, quality, size or support, and note the budget if one is given.
Return JSON: {"products": ["..."], "criteria": ["..."], "budget": "the budget, or null"}.
## @node: research_product
Research this one product:
{{item}}
Criteria to cover: {{shortlist.criteria}}
Find its current price from a shop or the maker, and a value for every criterion from reviews, specs or tests. Note where each fact comes from.
Return a JSON object: {"product": the name, "price": {"value": "...", "source": "link", "date": "..."}, "criteria": {"<criterion>": {"value": "...", "source": "link"}}, "notes": "anything a buyer should know"}.
## @node: fact_check
You are a fact checker. Check this research as if a stranger wrote it.
What the user wants: {{wish}}
The research, one entry per product:
{{research_product}}
Open the sources of the prices and of the specs that decide the choice, and confirm them. Make sure every product is judged on the same criteria. Correct what is wrong, and mark what could not be confirmed.
Return the checked facts per product, each with its source, then a short list of what you corrected or could not confirm.
## @node: verdict
Recommend one option for this request:
{{wish}}
Using only these checked facts:
{{fact_check}}
Return Markdown: a comparison table (one row per product, one column per criterion, plus price), the pick and why in two sentences, the best choice for a different need if there is one, and what to double-check before buying.
More workflows for a chat
- Research a topic and fact-check itSearch the web, check every claim against its source with fresh eyes, then a short answer with links
- Review my essay against a rubricScore each rubric criterion with quotes, suggest line edits, re-check every score, then the feedback
- Plan a trip and check the budgetDay-by-day plan with prices, a budget check that sends it back while it is over, then a booking list