--- title: Customs Compass emoji: 🧭 colorFrom: indigo colorTo: pink sdk: docker app_port: 7860 pinned: false license: mit short_description: AI compliance copilot for Chinese US exporters --- # 🧭 Customs Compass AI compliance assistant for Chinese SMEs (hardware, batteries, robotics, electronics) exporting to the United States. Built with Streamlit + Ollama. ## What it does Given a product description and/or a compliance question, Customs Compass produces a structured bilingual answer covering: - **US sales tax obligations** — state-by-state economic nexus thresholds, transaction rules, and base sales tax rates - **Customs duties** — HTS codes and duty rates by product category - **Federal certifications** — FCC, UL, FDA flags per product - **Risk assessment** — Low / Medium / High flags based on your sales vs. each state's threshold - **Source citations** — every claim cites the underlying CSV/JSON - **Live CBP news** — relevant headlines from `cbp.gov/newsroom` injected into the context (cached 1 hour) ## Architecture (hybrid) | Layer | Source | Update model | |------|--------|--------------| | Reference data | `nexus_thresholds.csv`, `hts_duty_codes.csv`, `tax_rates_by_state.json` | Manual / version-controlled | | CBP enforcement alerts | `cbp_alerts.csv` (curated from cbp.gov) | Manual / version-controlled | | CBP RAG corpus | `cbp_chunks.jsonl` (595 chunks) + `cbp_pages.jsonl` (200 pages) | Scraped from cbp.gov | | Retrieval | BM25-light (pure Python, title-boosted) | Index built at startup (~0.5s) | | Live news | `cbp.gov/newsroom` (scraped, cached 1h) | Auto on app load | | Reasoning | Ollama `llama3.2:3b` (local) | — | | Fallback | Deterministic rule-based templates | — | The app **always works offline**: if Ollama isn't running or the network is down, it gracefully falls back to a rule-based engine that still produces structured bilingual answers from the CSV data. ## Quick start ### 1. Install dependencies ```bash pip install -r requirements.txt ``` ### 2. (Recommended) Install & start Ollama Download Ollama from , then: ```bash ollama pull llama3.2:3b ollama serve ``` ### 3. Run the app ```bash streamlit run app.py ``` Open in your browser. ## Running without Ollama (fallback mode) The app detects whether Ollama is reachable at `http://localhost:11434`. If not, the sidebar will show **🟡 Ollama offline — fallback mode** and use a deterministic template engine that: 1. Extracts state names, product categories, and sales amounts from your question 2. Looks them up directly in the CSV files 3. Computes risk levels and produces a bilingual checklist You can also force fallback mode via the sidebar checkbox — useful for predictable, fast, offline-only responses. ## Data files ### `nexus_thresholds.csv` Economic-nexus thresholds for all 50 US states + DC. Columns: `state, threshold_usd, transaction_rule, notes` Note: most states use $100,000; large markets (Texas, California, New York) use $500,000; Oregon, Delaware, Montana, New Hampshire, and Alaska have no statewide sales tax (threshold set to 0). ### `hts_duty_codes.csv` Customs duties + federal certifications per product category. Columns: `product_category, hts_code, duty_rate, fcc_needed, ul_needed, fda_needed, notes` Categories: `battery_with_charger`, `battery_only`, `robotics_with_radio`, `consumer_electronics`, `medical_device`, `industrial_machinery`, `power_tools`, `led_lighting`, `drones`, `solar_panels`, `smart_home_devices`, `ev_charger`, `wearables`, `audio_equipment`. ### `tax_rates_by_state.json` Base state sales tax rates (percentages). No-tax states are set to 0. ### `cbp_alerts.csv` Curated CBP enforcement & tariff alerts pulled from `cbp.gov`. Critical for Chinese SME exporters. Columns: `category, title, summary, relevant_products, country_focus, severity, action_required, source_url` Covers: - **Section 301 tariffs** on Chinese electronics (+25%) - **Section 232** steel/aluminum derivatives - **De Minimis suspension** (EO 14324, effective Aug 29 2025) — all sub-$800 shipments now dutiable - **UFLPA** (Uyghur Forced Labor Prevention Act) — rebuttable presumption against XUAR-sourced goods - **AD/CVD** (Antidumping/Countervailing Duties) — solar, batteries, steel - **IPR seizures** — counterfeit electronics/batteries (China = 66% of FY2025 seizures) - **Lithium battery safety** — UN38.3, UL 2054 requirements - **IEEPA tariffs** — emergency authority for rapid tariff changes ## Example queries - "We sell power banks to Texas, $200k annual sales. Do we need to collect sales tax?" - "Our startup ships lithium batteries to California and New York. What certifications do we need?" - "Medical thermometer exports to Florida with $150k revenue — what are our obligations?" - "We're sending drones to Oregon. Any federal compliance needs?" ## Risk model The app classifies nexus risk in three bands relative to the state's economic threshold: | Risk | Sales vs threshold | Meaning | |------|--------------------|---------| | 🟢 Low | < 70% | No obligation; continue monitoring | | 🟡 Medium | 70% – 100% | Approaching nexus; register pre-emptively | | 🔴 High | ≥ 100% | Obligation triggered; register & collect immediately | ## Configuration Edit constants at the top of `app.py` to tune behavior: - `OLLAMA_MODEL` — switch to `llama3.2:1b` for faster responses, `qwen2:7b` for better Chinese - `NEWS_CACHE_TTL` — CBP news cache duration in seconds - `NEWS_FETCH_TIMEOUT` — HTTP timeout for CBP fetches ## Project structure ``` DD/ ├── app.py # Single-file Streamlit application ├── requirements.txt # streamlit, pandas, requests ├── nexus_thresholds.csv # Economic nexus data (50 states + DC) ├── hts_duty_codes.csv # Customs duties + certifications ├── tax_rates_by_state.json # State sales tax rates ├── cbp_alerts.csv # CBP enforcement & tariff alerts (Section 301, UFLPA, etc.) ├── cbp_pages.jsonl # CBP page corpus (200 full pages, metadata) ├── cbp_chunks.jsonl # CBP chunked corpus (595 chunks, ~4000 chars each) └── README.md # This file ``` ## How the RAG works When you ask a question, the app: 1. **Extracts** states, product categories, and sales amounts via regex/keyword matching 2. **Looks up** structured data: nexus thresholds, HTS codes, tax rates, curated CBP alerts 3. **Retrieves** the top-3 most relevant CBP page excerpts from `cbp_chunks.jsonl` using a **BM25-light scoring** (pure Python, no extra deps): - Tokenizes question + product names + state names - Scores each chunk via Okapi BM25 (k1=1.5, b=0.75) - Boosts terms appearing in the page **title** (2.5×) - Deduplicates so you get at most one chunk per source page 4. **Injects** all retrieved context into the LLM prompt (Ollama) or the fallback template engine 5. **Renders** a bilingual answer with risk flags and source citations ## Limitations - The included CSV data is for **demonstration only** and reflects general public information. Real engagements should verify against the latest state tax authority and CBP publications. - The CBP news fetcher relies on the public HTML structure of `cbp.gov/newsroom`. If CBP restructures the site, the fetcher will return an empty list (the app continues to function). - `llama3.2:3b` is a small model. Chinese output quality may vary; the fallback engine uses pre-translated templates for consistent Chinese. ## Disclaimer This tool provides **educational guidance only**. It does **not** constitute legal, tax, or customs advice. Always consult a licensed CPA, customs broker, or trade attorney before making compliance decisions. ## License Provided as-is for educational use.