
GoldenMatch
io.github.benseverndev-oss由 GitHub 帳號 benseverndev-oss 發布v3.13.0更新於 Oct 24, 2026
Find duplicate records in 30 seconds. Zero-config entity resolution, 97.2% F1 out of the box.
發布方自己的服務:match.bot
概覽
GoldenMatch 是零設定的實體解析伺服器,讓助理在表格式資料中找出重複的人、公司或產品,並合併成黃金記錄。
- 可以做什麼
- 去重記錄:對 CSV 或記憶體中的表格執行零設定比對,取得叢集、唯一列與合併後的黃金記錄
- 檢視並重用比對設定:讀取自動設定選定的精確、模糊與分塊規則,套用到新資料或自行覆寫
- 解析身分:穩定實體 ID、逐欄位來源、存活策略、合併/拆分、事件時間軸與稽核鏈,以及 Customer 360 檢視
- 剖析、評分與評估:Fellegi-Sunter 與 LLM 評分器、品質檢查、改善建議與自我驗證報告
- 處理非結構化輸入:先從 PDF 與圖片擷取記錄,再進行解析
- 適用情境
- 當資料集可能重複登錄同一個人、公司或產品,希望在不必撰寫比對規則、不必訓練模型的情況下分組並合併重複項時適用。也適合在 CRM、帳務系統與多份試算表來源之間建立持久的客戶身分層。
- 執行需求
- 可作為託管遠端端點執行,也可作為本機程序執行(PyPI 套件 goldenmatch,以 uvx 啟動,或以 mcp-serve 指令自行託管)。託管端點需在 Authorization 標頭提供 bearer 權杖;本機回環自架不需權杖。選用擴充可加入 LLM 評分、向量嵌入、Postgres 等連接器。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 GoldenMatch,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。
交給代理程式安裝
把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。
閱讀 https://sourceweft.com/mcp/io.github.benseverndev-oss%2Fgoldenmatch/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。其他 MCP 客戶端
把它新增到你客戶端的 mcpServers 設定中。
{
"mcpServers": {
"goldenmatch": {
"type": "http",
"url": "https://goldenmatch-mcp-production.up.railway.app/mcp/"
}
}
}README
GoldenMatch
Find the rows in your data that are the same person, company or product. No rules to write, no labelled pairs, no model to train.
Zero-config entity resolution for Python. Point it at a CSV or a table: it chooses how to match, shows you what it chose, and merges each group of duplicates into one golden record.
[PyPI: goldenmatch] [npm: goldenmatch] [Python] [Node] [License: MIT]
[CI] [codecov] [OpenSSF Scorecard] [Fellegi-Sunter beats hand-rolled Splink] [250M rows in 11.2 min]
[PyPI downloads (suite)] [npm downloads (suite)] [crates.io downloads] [GitHub stars]
v3.22.0: Zero-config person dedupe is 18-30x faster, and your records come back as you entered them. 250k rows went from 520 s to 18 s with identical clusters (upgrade pulls
goldenmatch-native0.2.3). The unique, duplicate and deduplicated tables now carry your original values instead of standardized ones;keep_original_values=Falseor--standardized-valuesrestores the old output.v3.21.0: No false alarms on small files, and no LLM calls you didn't ask for. A correct run on a small file no longer logs RED "output may be low-precision", and auto-config now turns on the (paid) LLM scorer only when you pass
llm_auto=True-- it used to do so whenever anOPENAI_API_KEYorANTHROPIC_API_KEYhappened to be set. If you relied on that, passllm_auto=Trueor setllm_scorerin your config.v3.20.0: Integer ID columns no longer crash zero-config. A CSV whose phone or account column is plain digits (read as int64) made
gm.dedupe(path)andgoldenmatch dedupedie withArrowNotImplementedErrorin auto-config's blocking; it now runs, and negative evidence on such a column scores instead of silently switching itself off. The CLI summary now says what it counts --12 records -> 7 entities (4 duplicate groups)-- andresult.total_entitiesmatches it.
Try it
Take a customers.csv where the same people were entered more than once:
GoldenMatch puts rows 1-3 together as one person and rows 4-5 as another. Thomas Becker and Thomas Baker share a zip code and stay separate. Each group becomes one golden record, built from the best value of each field. The run writes <timestamp>_deduplicated.csv, one row per person (the four golden records plus the three people who had no duplicate), and <timestamp>_golden.csv with the merged records alone.
From Python:
Already have the data in memory? gm.dedupe_df(table) takes a pyarrow Table or a polars DataFrame.
What it chose, and how to change it
Nothing here is a black box. On the file above, auto-config matched exactly on email and phone and fuzzily on name and address, and only compared records that share a zip. result.config holds that decision:
- Reuse it on new data:
gm.dedupe("next_month.csv", config=result.config). - Take over with your own rules:
gm.dedupe("customers.csv", exact=["email"], fuzzy={"name": 0.85}), or a YAML config. See configuration.
Beyond one file
Your customer data lives in a CRM, a billing system, and three spreadsheets nobody owns. Some records are duplicates. Some are the same company spelled four different ways. Nobody can answer how many customers do we actually have, and every dashboard built on top inherits the doubt.
Splink-beating entity resolution, Arrow-native and Rust-fast with zero tuning, feeding a durable identity layer so messy records from every source become stable golden entities with whole-record, Customer-360 provenance.
Zero-config matching that beats expert-tuned Splink head-to-head on messy customer records, in an Arrow-native, Rust-authoritative engine verified from a laptop CSV to a 250M-row dedupe in 11.2 minutes. The identities it produces live in a transaction-native control plane carrying stable entity_ids, per-field provenance, merge/split, and a tamper-evident audit log, all one call away as a Customer 360. It even owns its primitives: byte-identical, faster-than-rapidfuzz / jellyfish / FAISS Rust kernels, not rented dependencies.
Python · TypeScript · SQL, at 4-decimal parity · native in Postgres + DuckDB · edge WASM · 70+ MCP tools · beats hand-tuned Splink · 250M rows in 11.2 min
[GoldenMatch web workbench: pair drilldown with NL prose]
Pair drilldown in the web workbench: cluster members, field-level diff, and a one-line NL explanation per pair. pip install goldenmatch[web] then goldenmatch serve-ui <project>. More screenshots →
What you get: the golden entity
Most entity-resolution tools hand you clusters and stop. GoldenMatch keeps going: it resolves messy records into a durable golden entity, one per real-world customer, that survives re-runs, carries provenance on every field, and answers "who is this, and where did each value come from?" in a single call.
- A stable identity, not a throwaway cluster id. Every entity gets a stable
entity_id(UUIDv7) that persists across runs as new data arrives. Records are absorbed, entities merge or split, but the id an entity earns is the id downstream systems can rely on. Run-local cluster numbers reshuffle on every run; these don't. - Whole-record provenance. Every field of the golden record traces back to the source record that won it: which source, when it was last seen, and which survivorship strategy picked it. The values it didn't pick stay visible rather than being silently dropped. Provenance is on the whole unified record, not just the match decision.
- Governed by construction. Conflicting values collapse to one best value by an explicit survivorship policy (most-complete · source-priority · most-recent · majority-vote); every identity change lands in an append-only event timeline; and the log is sealed with a hash-chained, tamper-evident audit that a reviewer (or the other language port) can independently verify.
customer_360(entity_id) composes it into one read: golden record, per-field provenance, every linked source record, the event timeline, and the entity's relationship neighborhood:
What ships today vs. what's emerging. The identity spine is production-grade and in
main: stableentity_ids, per-field provenance, survivorship, merge/split, the append-only log + audit chain, cross-channel stitching, the relationship overlay, and incremental resolution against a persisted index (a new record resolves without a full re-run). Thecustomer_360()serving view above and the source-registry layer that keeps it fresh from live systems are the newer, actively-landing pieces. The source connectors (Snowflake, BigQuery, Salesforce, HubSpot) ship today; the registry that wires them into the spine is emerging. See the Customer 360 design + ADR. We label the seam rather than blur it.
The golden entity lives in the control plane; the matching that builds it runs in the compute engine. That split is the next section.
One product, two engines
The golden entity above is produced by two engines that optimize for genuinely different things, and keeping them distinct is the architecture, not an implementation detail (ADR 0047).
Many surfaces, one answer. The same capabilities reach Python, edge-safe TypeScript (with an opt-in WASM backend running the same Rust kernels), SQL inside PostgreSQL and DuckDB, and MCP / REST / A2A, all governed by specification + conformance, not copy-paste. There is one authoritative owner per capability; pure-Python / standalone-TS paths are classified, conformance-tested fallbacks. Where a boundary can't cross byte-for-byte, we measure and label it rather than claim parity.
Why a platform engineer should care:
- The compute layer isn't framework lock-in. It's Arrow-native and backend-replaceable, so you can push the heavy matching to a query engine that plans, spills, and distributes (verified to 250M rows) without the identity state coming along for the ride.
- The identity layer is a real state machine, not a columnar rebuild-every-time batch. Durable ids, transactional merge/split, provenance and audit are first-class operations you can integrate against.
- Behavior is consistent where it's shared. SQL, Python, and TypeScript track the same answers to a conformance spec, so the surface you build on isn't quietly inventing its own semantics.
Resolution that beats the expert
The identity layer is only as good as the matching underneath it, and the matching starts at zero config. dedupe_df(df) runs with no rules and no training data: it profiles the data, picks a defensible configuration, and returns golden records immediately. The config it chose comes back on result.config: inspectable, diffable, versionable. Never a black box.
- Beats the expert, out of the box. On messy customer records, the opt-in Fellegi-Sunter engine beats hand-tuned Splink head-to-head, with
historical_50kpairwise F1 0.827 vs 0.757, cluster B³ 0.862 vs 0.788, one shared evaluator, reproducible bake-off. Fuzzy, exact, probabilistic (Fellegi-Sunter), and LLM scorers, with EM-trained weights and calibrated scores. - A healing loop, not a one-shot. Zero-config gets you most of the way; then every run checks a free unsupervised signal and, when there's headroom, attaches ranked, self-verified config tweaks to
result.suggestions. Each is kept only if it doesn't worsen a health proxy, so a suggestion never makes results worse.dedupe_df(df, heal=True)applies and re-runs in one call. You close the gap to expert-tuned without being the expert. - Privacy-preserving record linkage. Match across organizations without sharing raw data: Bloom-filter PPRL, 92.4% F1 on FEBRL4, with HMAC-salted encodings.
- Self-verifying. Every step runs preflight + postflight checks and returns an inspectable report instead of failing silently. That is the "advanced, never black-box" contract that makes an automated identity layer safe to build on.
Runs on unstructured input, too: extract records from PDFs and images, then resolve them like any other source (
pip install goldenmatch[documents]).
Runs where your stack is
The engine and the identity layer reach your stack through the surface you already use, with the same capabilities governed by conformance (one product, two engines) rather than re-implemented thinly per surface.
- SQL-native, at parity. The same functions run inside PostgreSQL (pgrx extension) and DuckDB: dedupe · match · score · auto-config + telemetry · identity-graph reads · profiling ·
evaluate· Fellegi-Sunter scoring · GoldenFlow transforms. Resolve without moving data out of the warehouse. - Python and edge-safe TypeScript. The full suite ships on npm alongside PyPI. The TS cores are dependency-free and
node:*-free (browsers, Cloudflare Workers, Vercel Edge, Deno); an opt-in WebAssembly backend (await enableWasm()) swaps in the same pyo3-free Rust kernels the Python wheels and SQL UDFs use, with pure-TS as the byte-identical default. - AI-native by default. Every package ships an MCP server, a REST API, and an A2A agent surface (70+ MCP tools across the suite), all exposing the same JSON telemetry shape across web, TUI, CLI, Postgres, DuckDB, and MCP.
- Spark, with no Python on the executors. The Rust kernels ride into a Spark cluster in one jar (
spark.addArtifact("goldenmatch-spark.jar")) and are called over JNI, so executors need no goldenmatch virtualenv, no packed env, nothing installed. Fellegi-Sunter training runs distributed on that path -- the E-step is a SparkGROUP BYover agreement patterns, so the cluster does the counting and the driver only fits the model. Deployment story, not a throughput one: the JVM scoring path measured ~2.4x slower than the Python-worker path, and the reason to use it is that there is nothing to install. - Pipeline-native. A dbt package (dedupe/match materializations, quality tests, identity-graph reads), a GitHub Action (fail PRs on data-quality regressions), and 13 drop-in Airflow DAGs (Deploy).
- Production paths. Postgres sync, daemon mode, lineage tracking, review queues.
Cross-language parity
Surface parity is not the same as handing any pipeline phase from one language to the other byte-for-byte. Each verdict below is measured by a conformance harness, not assumed:
Rule of thumb: hand off at the cluster or identity boundary and it's seamless; don't split across standardize/dates, embeddings, or the controller and expect bit-exact reproduction. Full detail + the runnable harness that keeps these verdicts honest: Cross-language parity & phase-handoff limits.
The suite: the pipeline into the spine
GoldenMatch is the headline, but resolution is only as good as what feeds it. Five sibling tools clean, standardize, and map records before they reach the identity layer. Each stands alone, but they compose into one pipeline, orchestrated declaratively by GoldenPipe:
The deepest docs live in packages/python/goldenmatch/README.md (~1,300 lines: full feature list, CLI, architecture, benchmarks).
Shared components
Not pipeline stages — the pieces the stages agree through, and the single front door an agent points at.
Owned libraries (standalone)
The suite owns its string-matching primitives instead of renting them: byte-identical drop-in replacements, published on their own so they're usable outside the suite too.
Knowledge graphs
Entity resolution is the stage most GraphRAG pipelines do worst: duplicate surface forms of one entity scatter across documents. Two packages put GoldenMatch's resolution there:
Measured, not asserted (ER-KG-Bench): resolution scores F1 0.602 on the labelled set, ahead of Neo4j-KGBuilder (0.456), neo4j-graphrag (0.403), and MS-GraphRAG / LightRAG / Cognee / mem0 (0.066). A resolved graph also does two things passage-window RAG structurally can't: exact aggregation (size-invariant where RAG recall collapses 0.99 → 0.64 across cluster-size buckets) and temporal as-of (1.000 vs 0.002 on past-date queries).
Scale & benchmarks
Every headline number maps back to a single committed runner (scripts/run_benchmarks.py); see docs/reproducing-benchmarks.md for per-number commands, dataset URLs, and expected output with tolerance.
- Accuracy on customer-shaped data. NC Voter 0.9719 F1 (real-data sample), Febrl3 0.9912 F1; the opt-in Fellegi-Sunter path beats hand-tuned Splink head-to-head on every dataset Splink scores (bake-off). (Bibliographic DBLP-ACM lands 96.4% F1 for the record-linkage crowd, but customer identity is the focus.)
- Privacy-preserving. PPRL 92.4% F1 on FEBRL4, matching across parties with no shared raw data.
- Scale envelope (
docs/scale-envelope.md): per-backend ranges (in-memory/bucket to a few M · DuckDB out-of-core to ~50M · Ray distributed ≥ 50M), block-size failure modes, and a decision tree for picking a backend.
Verified on the Ray tier: a full 100M-row dedupe on a 5-node Ray cluster in 9.2 min (554 s), 20,000,000 golden records recovered exactly, driver peak 0.36 GB RSS. (The larger 250M / 11.2 min headline is the Spark tier on a different cluster shape -- the two are separate lanes, not one number superseding the other, and this one is what carries the recall-complete guarantee below.) The default distributed path is recall-complete: duplicates merge correctly no matter how the input is partitioned (blocking-key shuffle scoring + distributed randomized-contraction WCC), and it stays driver-collect-free end to end. Recipe: configs/distributed-100m.yaml.
Fellegi-Sunter training, distributed on Spark: the E-step collapses to one Spark GROUP BY over agreement patterns, so training cost tracks the number of DISTINCT comparison vectors (bounded by prod(levels + 1)), not the pair count. Measured on a real 2-worker Spark cluster (jar-only executors, no Python installed), 1M -> 5M rows: candidate pairs grew 5.00x and the distributed counting stage 5.25x, while distinct patterns grew 3.0% (433 -> 446) and driver-side EM stayed at 0.01s. That is the property the tier rests on -- the cluster absorbs the data, the driver's work stays flat.
Head-to-head vs Splink on a real Spark cluster, at 50M rows. Both engines on the same 5-node cluster, the same fixture, the same shared metric implementation, and Splink configured the way its own performance guide prescribes -- break_lineage_method="parquet" onto a real distributed filesystem, shuffle partitions at 5x cluster cores, and identical 48 GB executors. Over 463,923,179 candidate pairs, scored identically by both:
Reported with it, because a benchmark that only publishes its wins is not evidence: the margin still narrows with scale (2.54x at 1M -> 1.91x at 50M), single runs on this lane move ~16% so no one ratio should carry much weight, zero spill was scale-bounded on the build that curve measured (true at 50M, 56.4 GB at 100M, 201.3 GB at 250M -- since taken to zero at 250M by #2698, so the caveat describes the curve rather than the shipped path), the fixture is synthetic, and the accuracy figures in it are not an accuracy verdict -- for that, see the bake-off. Measured further since: 250M rows / 2.32 billion pairs in 670s on the same 5-node cluster, no executor deaths and zero failed tasks, at 0.289 seconds per million pairs -- 4.13x faster than the 2,766s that curve first measured, with 3.1x less executor CPU, zero spill and a byte-identical trained model. Cost stays linear in PAIRS rather than rows; the constant got four times smaller. Four earlier attempts at this comparison were invalid because we had misconfigured Splink; each defect and its effect is documented alongside the results. Full method, caveats and reproduce command.
Three reproducible real-world pipelines run this on public data at scale:
- shell-company-network: investigative ER across ICIJ Offshore Leaks + OpenSanctions + GLEIF + UK PSC. −62.5% analyst-hours to triage vs single-source baselines.
- vuln-attribution: 6,126,895 OSS-vulnerability records → 847,475 canonical vulns across 40 sources in ~5 minutes on one 64GB runner.
- sanctions-reconciliation: cross-list coverage on 85 public sanctions lists across 50+ jurisdictions.
Install & quick start
Dedupe a CSV in 30 seconds, zero config, writes <timestamp>_golden.csv:
The whole suite, configured for speed. golden-suite pulls in every package plus the native (Rust) kernels, pinned and defaulted to the perf-optimized config. Native wheels are hard dependencies on purpose: a platform without a wheel fails loudly rather than silently running the slow pure-Python path.
Just GoldenMatch. Fat optional extras, so you pay only for what you use (native acceleration is default on common platforms):
Web workbench. pip install 'goldenmatch[web]' then goldenmatch serve-ui my-project (opens http://localhost:5050): edit rules with live validation, preview against a sampled slice, label pairs (mirrored into Learning Memory), compare runs.
More: examples/, covering Python (quickstart, full pipeline, customer 360, PPRL, MCP client) · TypeScript (quickstart, Vercel Edge, MCP client) · Airflow.
Deploy
Remote MCP. The hosted endpoint requires a bearer token -- it exposes tools that read and write files on the server, so it is not open. Ask the maintainer for one, or self-host: goldenmatch mcp-serve --transport http is the same server.
Self-hosting on loopback needs no token; binding to a public interface without
GOLDENMATCH_MCP_TOKEN is refused rather than served open.
Containers. Every package ships as a multi-arch image (linux/amd64 + arm64) on GHCR, pull anonymously:
Airflow. 13 drop-in DAGs at examples/airflow/ (TaskFlow API, Airflow 2.7+ / 3.x; idempotent, marker-protected), grouped by lifecycle stage:
Repository layout
- Cargo: no root workspace.
packages/rust/extensions/is itself a Cargo workspace (thepostgrescrate is excluded for pgrx); Cargo commands run from inside it. - TypeScript: one pnpm workspace.
packages/typescript/*form a single pnpm + Turborepo workspace.
Contributing
- Feature work on
feature/<name>branches; merge via squash PR. Titles:feat:/fix:/docs:. - Tests must pass on all three languages where the change applies; the parity harness in
packages/typescript/goldenmatch/tests/parity/enforces 4-decimal Python ↔ TypeScript scorer parity. - Architecture changes conform to (or amend) the one-product-two-engines frame in the same PR. Design rationale lives in
context-network/decisions/anddocs/superpowers/specs/.
Windows: enable Developer Mode so pnpm install can create symlinks; if corepack enable needs admin, npm i -g [email protected] is equivalent.
This repo was formed on 2026-05-01 by folding 8 sibling repos into goldenmatch via git filter-repo (full history preserved). Built by Ben Severn. MIT, see LICENSE.
來源:README.md,提交 6d6498b
工具
0版本歷史
1- v3.13.0最新Sep 16, 2026
評分
已滿足適用檢查項的 85%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通必需25 分
- 已宣告認證方式必需10 分
- 已列出工具必需15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
其他 Match 整合
match.bot
bot.match官方發布者
AI 代理程式的免費會面場所:註冊、查詢代理程式、點贊、接受介紹。檢視 whats_waiting。AI 翻譯

Ofac Match
由 GitHub 帳號 krunalsolanki 發布
在本機執行的 MCP 伺服器,用 OFAC SDN 制裁名單篩選姓名,並解釋每個比對分數的由來。

onet-match
由 GitHub 帳號 Benjamin-V-Chan 發布
本機 MCP 伺服器,把職稱、履歷或技能清單等自由文字對應到排序後的 O*NET-SOC 職業代碼,並附上任務、技能與 RIASEC 興趣。

PaintColorHQ Color Match
由 GitHub 帳號 pcameron80 發布
託管式 MCP 伺服器,可依任意十六進位色碼在 13 個品牌中找出最接近的真實可購買塗料顏色,並以 CIEDE2000 評分。
Nityaflow GST credit match
in.nityaflow
遠端 MCP 伺服器,用於印度 GST 進項稅額扣抵核對、收據驗證,以及 AI 代理付款前的授權檢查。