Storekeeper is an open-source AI customer-support agent I built for Shopify. It reads a customer’s message, checks store rules, and queues eligible refunds, cancellations, and address changes for human approval. It also answers policy questions and drafts a reply for the operator.
I built it to explore how an agent can work with a real store without giving the model control over business rules. The model extracts requests and writes replies. Python code checks eligibility, controls execution, and requires a human decision before each order change.
Building the workflow
I started with a CLI and a live Shopify development store. A resumable seed script created 50 test orders covering recent, fulfilled, old, and high-value cases. That let me check the rules against real Shopify data before adding a UI.
LangGraph connects order lookup, policy checks, approval, and execution. SQLite checkpoints save pending approvals, so an operator can close the process and decide later. The policy gate is plain Python: cancellations and address changes require an unfulfilled order, refunds have a 30-day window, and high-value refunds get flagged for review.
Working with Shopify taught me a few things the happy path wouldn’t show. An imported order’s creation timestamp can differ from its original order date, so the refund rule uses processedAt. An order marked paid can still have no captured payment to reverse. I updated the seed data and used Shopify’s suggestedRefund to determine which transactions to refund. Refund writes also use an order-derived idempotency key to guard against duplicate execution.
Order lookup requires a plain order number and an exact match with the returned order. Address changes need complete delivery details and show the current and proposed addresses before approval.
Bringing it into the browser
I added policy retrieval with local Chroma embeddings, then a FastAPI API and React operator console. Policy questions retrieve relevant sections from Markdown documents. Code drops cited filenames that weren’t supplied to the answering model; the Python gate still decides whether an action is eligible.
The console uses the same graph as the CLI. Operators can create tickets, review the matched order and policy reason, approve or reject actions, and copy reply drafts. FastAPI serves the built console and API from one process. Optional LangSmith traces show where model calls, policy checks, and approvals happen.
I later extended the workflow to handle several requests in one message. Python validates the classifier’s task list, and LangGraph runs independent tasks in parallel. Each write pauses on its own approval card. Once every task finishes, the model drafts one reply in the customer’s original request order. Multiple writes for the same order go to human review before dispatch.
Current scope
Storekeeper is an early v2 prototype for one operator using a development store. Tickets are entered manually, replies stay as drafts, and the local console has no authentication. Helpdesk integrations and recovery for failed registered runs remain unfinished.
The repository includes offline tests for policy boundaries, order matching, write controls, parallel approvals, citation filtering, persistence, and API behavior, alongside documented live-store checks.