swapit — 家庭有害物質盤點與替代方案引擎 是做什麼的?
這個技能是做什麼的
swapit 能將模糊的擔憂(「我家裡大概有很多塑膠和 BPA」)轉化為具體、優先、可追蹤的計畫。它是有狀態的:你的家庭物品清單存在磁碟上,並跨工作階段持續存在。它是本機優先的:零付費服務,除非你明確選擇加入 (M3) 共享知識庫,否則所有資料都不會離開你的裝置。
一次執行可以產生:
- 一份物品清單,列出你擁有的物品,每個物品都標有其通用的物品類別。
- 每件物品的風險評分,反映實際暴露程度 — 每天高溫使用的刮傷不沾鍋,風險遠高於車庫中未開封的塑膠箱。
- 一份排序的「優先取代清單」 — 能最大程度降低暴露風險的 5% 改變。
- 取代追蹤 — 選擇的替代方案、採購狀態、檢查清單、書籤。
- 一份可分享的 HTML 報告(在 M2 中,還有
swapit serve的即時儀表板)。
三個領域(以及隱私不變性)
| 領域 | 內容 | 分享性 |
|---|---|---|
| 1 · 知識 | 危害 → 物品類別 → 替代方案(通用、引用的事實) | 可分享;快取 + (M3) 共享知識庫同步 |
| 2 · 物品清單 | 你的物品、房間、數量、品牌、照片、取代、書籤 | 私密 — 絕不離開裝置 |
| 3 · 共享知識庫 (M3) | 匿名貢獻,豐富共享的知識圖譜 | 選擇加入,經審查,僅限通用事實 |
隱私不變性(具約束力): 領域-2 物品清單(物品、房間、數量、品牌、照片、購買資訊、位置)絕不跨越同步邊界。只有領域-1 的通用事實可分享,且需經明確選擇加入 + 可審查的
swapit sync --dry-run。由客戶端上的允許清單序列化器 (scripts/anonymize.py) 以及共享知識庫伺服器上的後備防護強制執行,並輔以模糊測試,斷言每個真實物品清單項目都會被閘門拒絕。禁止欄位清單:anonymize.CONTRIBUTION_FORBIDDEN(state.PRIVATE_FIELDS中物品清單結構的子集)。
資料模型
狀態資料位於 ~/.config/swapit/(可用 $SWAPIT_HOME 覆蓋;遵循 $XDG_CONFIG_HOME)。
~/.config/swapit/
├── knowledge/ hazards.jsonl · item-classes.jsonl · alternatives.jsonl · products.jsonl · procurement.jsonl
├── inventory/ events.jsonl(僅附加稽核) · items.json · swaps.json · rooms.json · bookmarks.json
├── contributions/ queue.jsonl (M3)
├── sync/ config.json · sync-log.jsonl (M3)
└── photos/
節點架構(完整、引用資料集請參閱 seed/*.jsonl):
- hazards —
id · name · aliases · class · mechanism · exposure_routes · regulatory · severity(0-3) · evidence_strength · sources - item_class —
id · name · category · description · hazards[]{hazard_id, presence_likelihood, rationale} · detection_hints · sources - alternative —
id · name · replaces[] · material · rationale · tradeoffs · caveats · avoids_hazards · residual_concerns · sources - procurement_option(何處購買,公開) —
id · alternative · item_class · retailer · region(ISO-3166-1 a2) · area · url · price_min · price_max · currency · as_of · availability · confidence · corroboration_count - item(私密) —
id · name · item_class · room · quantity · brand · condition · usage{frequency, food_contact, heat, child_contact} · status · notes · photos - swap(私密) —
id · item_id · chosen_alternative · procurement{status, cost, vendor} · checklist[] · bookmarks[]
風險模型
risk = severity × presence_likelihood × evidence × exposure_relevance × frequency × condition
- exposure_relevance 會根據物品的使用方式啟動危害的暴露途徑(食品接觸 + 高溫會將食入/食品接觸/高溫危害最大化;皮膚接觸對個人護理品很重要;吸入對清潔/家具很重要;兒童接觸會放大)。
- 物品分數 = 每個危害風險的加權總和 → 劃分為高 / 中 / 低等級。
- 這是優先排序的智慧 — 類似於採購技能的「主導失效模式」:先修復造成大部分暴露的少數物品,而不是列出一份讓人有罪惡感的全部塑膠清單。
模式
| 模式 | 功能 |
|---|---|
init | 建立狀態 + 載入種子知識圖譜 |
add | 新增家庭物品(名稱、類別、房間、狀態、使用方式) → 顯示其評估結果 |
assess | 評估物品或臨時物品類別 → 危害 + 風險 + 排序的替代方案 |
list | 列出物品清單,依 --room/--band/--status/--class/--hazard 篩選,依風險排序 |
swap | 建立/更新取代計畫:選擇替代方案,設定狀態、檢查清單、書籤、成本 |
score | 家庭暴露摘要 + 優先取代排名 |
report | 產生自包含的 HTML 報告(類別-C) |
procure | 採購技能交接簡報 + 針對取代目標的已知購買管道(依 --region 篩選);記錄找到的管道(--retailer/--url/--price-*)到公開共享知識庫 |
knowledge | 瀏覽/搜尋知識圖譜(list/search/show) |
rooms | 列出/新增房間 |
selfheal | 驗證知識邊緣 + 物品清單引用 + 基礎事實;錯誤時以非零狀態碼退出 |
serve | 本機即時儀表板於 http://127.0.0.1:8731 — 看板、檢查清單、書籤、狀態;每次點擊都會寫回狀態 |
contribute | 將匿名事實排入佇列 — product / hazard (item-class→hazard) / alternative / procurement(公開購買管道)/ item-class(新分類節點);在本機套用 + 經閘門控管後進入共享知識庫 |
sync | 推送貢獻佇列 + 拉取社群知識(選擇加入);--dry-run 預覽將發送的確切內容;--configure 設定端點 |
典型流程
swapit init
swapit add --name "舊的不沾鍋" --class nonstick-cookware --room kitchen \
--condition scratched --frequency daily --food-contact --heat
swapit score # 看看優先取代什麼
swapit swap itm_xxxx --to cast-iron-skillet --status sourcing --add-task "買一個10吋鑄鐵鍋"
swapit procure itm_xxxx # -> 將簡報交給 `procurer` 技能
swapit report --open # 可分享的 HTML
與其他技能協作
procurer—swapit procure <item>建立需求(「更換 3 個聚碳酸酯水瓶為玻璃/不鏽鋼」)和現成的採購提示;procurer回傳引用來源 + 預算範圍。bookkeeping(P6) — 一個新穎、持久的危害/產品發現(例如新表徵的物品類別)會主動歸檔到research/entities/,之後可流入共享知識庫。health— 個人暴露背景。content-creation— 從知識圖譜產生教育文章。
基礎事實紀律
種子知識僅引用權威機構(NIEHS、ATSDR/CDC、US EPA、US FDA、ECHA/EU REACH、CA OEHHA Prop 65、WHO、EWG)。每筆記錄都有 ≥1 個來源;verified: false 標記這些為參考級(非最新擷取)——執行一次來源更新(或透過共享知識庫)來重新整理。selfheal 在任何節點失去引用時會失敗。這是基於公共衛生科學的消費者指導,非醫療或法律建議。
資源
scripts/swapit.py— CLI 入口點 + 指令處理器scripts/state.py— 兩個領域的狀態層(PRIVATE_FIELDS定義同步邊界)scripts/ops.py— 單一狀態變更寫入路徑(CLI 與儀表板共用)scripts/knowledge.py— 知識圖譜載入 + 邊緣解析scripts/risk.py— 暴露風險評分引擎scripts/report.py— 自包含 HTML 報告產生器(類別-C)scripts/server.py—swapit serve即時儀表板(標準庫 http.server,僅限本機)scripts/anonymize.py— 隱私閘門:允許清單事實建構器 + 禁止欄位掃描scripts/sync.py— 共享知識庫同步客戶端(佇列、--dry-run預覽、推送/拉取、合併)scripts/selfheal.py— 完整性驗證器templates/dashboard.html— 即時儀表板(內嵌 CSS/JS,類別-C)commons/— 網路共享知識庫參考伺服器(FastAPI + SQLite;部署需經過閘門)seed/{hazards,item-classes,alternatives}.jsonl— 有基礎事實的起始知識tests/— 風險、知識、自我修復、CLI、隱私/匿名化、同步、報告和伺服器測試
協作(共享知識庫)
貢獻僅限於通用事實 — swapit contribute product|hazard|alternative|procurement|item-class 建立一個匿名化事實(公開產品→物品類別映射、危害邊緣修正、替代方案、購買管道或新的分類節點),在本機套用並排入佇列。swapit sync --dry-run 顯示完全將被傳送的內容;swapit sync 推送佇列並拉取社群知識(選擇加入,在 --configure 之後)。來自不同使用者的相同事實會相互佐證(以內容定址)而非重複;共享知識庫在兩個不同貢獻者確認該事實後才提供該事實(corroboration >= 2)——審核是以佐證為門檻,非信任度為門檻,因為 confidence 由呼叫者提供,單一提交者可能自我核准。隱私不變性在兩端(客戶端 anonymize 閘門 + 伺服器後備防護)強制執行——物品清單永不跨越。
購買管道(採購)共享知識庫
一個 procurement_option 事實是一個公開管道:由 retailer 在 region(ISO-3166-1 alpha-2)銷售的較安全 alternative,附有可選的 url、price_min/price_max + currency + as_of、area 和 availability。它以 (alternative, retailer, region) 的組合進行內容定址——跨使用者佐證同一管道;不同地區則視為不同事實(地理尺度軸線)。價格/網址/區域是可細化的市場資料:佐證一個嚴格更新 as_of 的事實會將價格向前更新,絕不會回歸更新的資料。隱私界線清晰——公開管道使用 retailer + price_*,絕不使用私密的 vendor/cost(你在哪裡買以及付了多少錢留在領域 2)。swapit procure <item> --region <CC> 會顯示已知管道,並記錄你找到的新管道——建立一個開放、詳細、地理範圍明確的資料集,任何人都可以使用。
路線圖
- M1(已發布,0.1.0) — 資料模型、種子知識、CLI、風險引擎、靜態 HTML 報告、自我修復。
- M2(已發布,0.2.0) —
swapit serve:具有讀/寫回狀態功能的即時本機儀表板。 - M3(0.3.0) — 匿名化協作 + 網路共享知識庫(
commons/,FastAPI + SQLite)。透過允許清單序列化 + 客戶端和伺服器端的模糊測試強制執行隱私不變性。 - M4(本次發布,0.4.0) — 地理擴展的採購共享知識庫 + 分類學成長:
procurement_option(公開購買管道,以(alternative, retailer, region)為鍵,僅向前更新價格)和item_class(以佐證為門檻的分類學成長)事實類型;procure顯示 + 記錄管道;跨 US/CO/DE/GB 的種子管道;跨語言雜湊奇偶校驗由固定向量鎖定。部署到 broomva.tech 基礎設施須經明確許可(憑證/DNS);該技能在離線狀態下也能完全正常運作。