InferMap

io.github.benseverndev-oss由 GitHub 帳號 benseverndev-oss 發布v0.7.0更新於 Oct 24, 2026

Map messy columns to a known schema — 7 scorers, domain dictionaries, F1 0.84. Zero config.

已驗證Streamable HTTP可網頁執行資料庫資料與分析

概覽

AI 產生的概覽

InferMap 是以 MCP 伺服器形式提供的結構描述對應引擎,讓助理把凌亂的來源欄位對應到已知的目標結構描述,並附上信心分數與理由。

可以做什麼
  • 對應來源與目標欄位集合(CSV、Parquet、XLSX、DataFrame、記憶體資料、SQLite/Postgres/DuckDB 資料表),取得附信心分數與說明的一對一欄位對應
  • 檢視檔案或資料庫資料表的結構描述
  • 將對應結果存成可重複使用的設定檔,之後不必重新推論即可載入
  • 把已儲存的對應套用到資料集以重新命名欄位
  • 用已儲存的設定檔驗證來源資料,包含必填欄位
  • 透過領域詞典、評分器權重、自訂評分器與信心校準來調整引擎
適用情境
適合需要把 CRM 匯出檔、供應商檔案或舊系統資料表對齊到統一結構描述的場合,也適合在資料管線中建立可重複的欄位重新命名與驗證步驟。適用於欄位名稱不同但語意重疊的資料工程與分析工作。
執行需求
可作為遠端 streamable HTTP 端點使用,也可作為本機程序執行;Python 套件可透過 uvx 執行,也可從 PyPI 安裝,另有 npm 上的 TypeScript 套件。使用 Postgres、MySQL 或 DuckDB 提供者需安裝選用的資料庫擴充。未宣告驗證、環境變數或標頭。
安裝前請注意
README 指出此儲存庫已移入另一個 monorepo,本儲存庫已封存,使用前應確認端點提供的是哪個版本。對應結果是推論而來,並非保證,套用到真實資料前應檢查低信心的配對。資料庫提供者可能會讀取所連線資料庫的資料表結構與樣本值。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 InferMap,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.benseverndev-oss%2Finfermap/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "infermap": {
      "type": "http",
      "url": "https://infermap-mcp-production.up.railway.app/mcp/"
    }
  }
}

README

Moved. This repo has moved into the benzsevern/goldenmatch monorepo at packages/python/infermap (and packages/typescript/infermap)/. This repo is archived; new development happens in the monorepo.

infermap

Inference-driven schema mapping engine.
Map messy source columns to a known target schema — accurately, explainably, with zero config.
Built by Ben Severn.

[PyPI] [npm] [PyPI downloads] [npm downloads] [CI]

[Python 3.11+] [Node 20+] [TypeScript] [Edge runtime] [Parity] [License: MIT]

📖 Wiki · 🌐 Docs · 🧪 Examples · 💬 Discussions · 🐛 Issues


infermap is a schema-mapping engine. Give it any two field collections (CSVs, DataFrames, database tables, in-memory records) and it figures out which source field corresponds to which target field, with confidence scores and human-readable reasoning. Available as a Python package on PyPI and a TypeScript package on npm, with mapping decisions verified bit-for-bit by a shared golden-test parity suite.

Table of contents

Install

Python

bash
pip install infermap

Optional database extras:

bash
pip install infermap[postgres]   # psycopg2-binarypip install infermap[mysql]      # mysql-connector-pythonpip install infermap[duckdb]     # duckdbpip install infermap[all]        # all extras

TypeScript / Next.js

bash
npm install infermap

Zero runtime dependencies in the core entrypoint. Compatible with Next.js Server Components, Route Handlers, Server Actions, and the Edge Runtime out of the box. See the package README for the full reference.

Quick start

Python

python
import infermap
# Map a CRM export CSV to a canonical customer schemaresult = infermap.map("crm_export.csv", "canonical_customers.csv")
for m in result.mappings:    print(f"{m.source} -> {m.target}  ({m.confidence:.0%})")# fname -> first_name  (97%)# lname -> last_name   (95%)# email_addr -> email  (91%)
# Apply mappings to rename DataFrame columnsimport polars as pldf = pl.read_csv("crm_export.csv")renamed = result.apply(df)
# Save mappings to a reusable config fileresult.to_config("my_mapping.yaml")
# Reload later — no re-inference neededsaved = infermap.from_config("my_mapping.yaml")

TypeScript

ts
import { map } from "infermap";
const crm = [  { fname: "John", lname: "Doe", email_addr: "[email protected]" },  { fname: "Jane", lname: "Smith", email_addr: "[email protected]" },];
const canonical = [  { first_name: "", last_name: "", email: "" },];
const result = map({ records: crm }, { records: canonical });
for (const m of result.mappings) {  console.log(`${m.source} → ${m.target}  (${m.confidence.toFixed(2)})`);}// fname       → first_name  (0.44)// lname       → last_name   (0.48)// email_addr  → email       (0.69)

For Next.js, drop it directly into a Route Handler — works on Edge Runtime with zero config:

ts
// app/api/infer/route.tsimport { map } from "infermap";export const runtime = "edge";
export async function POST(req: Request) {  const { sourceCsv, targetCsv } = await req.json();  const result = map({ csvText: sourceCsv }, { csvText: targetCsv });  return Response.json(result);}

How it works

Each field pair runs through a pipeline of 7 scorers. Each scorer returns a score in [0.0, 1.0] or abstains (None/null). The engine combines scores via weighted average (requiring at least 2 contributors), then uses the Hungarian algorithm for optimal one-to-one assignment.

ScorerWeightWhat it detects
ExactScorer1.0Case-insensitive exact name match
AliasScorer0.95Known field aliases (fname ↔ first_name, tel ↔ phone) + domain dictionaries
InitialismScorer0.75Abbreviation-style names (assay_id ↔ ASSI, confidence_score ↔ CONSC)
PatternTypeScorer0.7Semantic type from sample values — email, date_iso, phone, uuid, url, zip, currency
ProfileScorer0.5Statistical profile similarity — dtype, null rate, unique rate, length, cardinality
FuzzyNameScorer0.4Jaro-Winkler similarity on normalized field names (with common-prefix canonicalization)
LLMScorer0.8Pluggable LLM-backed scorer (stubbed by default)

The engine also applies common-prefix canonicalization — automatically stripping schema-wide prefixes like prospect_ so that City vs prospect_City is compared as City vs City. And optional confidence calibration transforms raw scores into calibrated probabilities post-assignment (ECE from 0.46 to 0.005 on real-world data).

Read the full architecture →

Features

PythonTypeScript
7 built-in scorers✅✅
Hungarian assignment✅ (scipy)✅ (vendored)
Custom scorers@infermap.scorerdefineScorer()
Domain dictionaries✅ (YAML)✅ (inlined)
Confidence calibration✅ (Identity/Isotonic/Platt)✅
Score matrix inspection✅✅
In-memory dataPolars, Pandas, list[dict]Array<Record>
File providersCSV, Parquet, XLSXCSV, JSON
Schema definition filesYAML + JSONJSON
Database providersSQLite, Postgres, DuckDBSQLite, Postgres, DuckDB
Engine configYAMLJSON
Saved mapping formatYAMLJSON
CLI✅ (Typer)✅ (node:util)
Apply to DataFrame✅❌ (CSV rewrite via CLI)
Edge-runtime compatible❌✅
Zero runtime depsn/a✅
Accuracy benchmark✅ (162 cases, F1 0.84)✅ (parity within 0.0005)

Full feature parity matrix →

Which package should I use?

If you are…Use
Building a Python data pipeline or notebookPython
Building a Next.js app, Node service, or browser toolTypeScript
Running mapping in a serverless edge functionTypeScript (zero Node built-ins)
Doing ad-hoc CSV exploration on the command linePython CLI has more features; TS CLI is leaner
Both — Python backend + Next.js admin UIBoth — outputs are interoperable via the JSON config format

What's new in v0.3

+18.3pp F1 on real-world data from four compounding improvements:

v0.2 baseline    F1 0.657+ min_conf 0.2   F1 0.765  (+10.8pp — empirically tuned threshold)+ prefix-strip   F1 0.821  (+5.6pp  — City vs prospect_City now works)+ InitialismScorer F1 0.840 (+1.9pp  — ASSI, CONSC, RELATIT now work)

New features:

  • Domain dictionaries — MapEngine(domains=["healthcare"]) loads curated aliases for your domain. Ships: generic (default), healthcare, finance, ecommerce. See examples/09_domain_dictionaries.py.
  • Confidence calibration — MapEngine(calibrator=cal) transforms raw scores into calibrated probabilities. Ships: IsotonicCalibrator, PlattCalibrator. Valentine ECE: 0.46 → 0.005. See examples/10_calibration.py.
  • InitialismScorer — matches abbreviation-style column names (assay_id ↔ ASSI). ChEMBL F1: 0.524 → 0.819.
  • Common-prefix canonicalization — automatically strips prospect_, assays_, etc. before fuzzy matching.
  • Valentine corpus — 82 real-world schema-matching cases from the Valentine benchmark for accuracy testing.
  • Full TypeScript parity — all new features ported. 186 TS tests. Benchmark F1 within 0.0005 of Python.

Custom scorers

Python

python
import infermapfrom infermap.types import FieldInfo, ScorerResult
@infermap.scorer("prefix_scorer", weight=0.8)def prefix_scorer(source: FieldInfo, target: FieldInfo) -> ScorerResult | None:    if source.name[:3].lower() != target.name[:3].lower():        return None    return ScorerResult(score=0.85, reasoning=f"Shared prefix '{source.name[:3]}'")
from infermap.engine import MapEnginefrom infermap.scorers import default_scorers
engine = MapEngine(scorers=[*default_scorers(), prefix_scorer])

TypeScript

ts
import { MapEngine, defaultScorers, defineScorer, makeScorerResult } from "infermap";
const prefixScorer = defineScorer(  "prefix_scorer",  (source, target) => {    if (source.name.slice(0, 3).toLowerCase() !== target.name.slice(0, 3).toLowerCase()) {      return null;    }    return makeScorerResult(0.85, `Shared prefix '${source.name.slice(0, 3)}'`);  },  0.8 // weight);
const engine = new MapEngine({  scorers: [...defaultScorers(), prefixScorer],});

CLI examples

The CLI works the same way in both packages:

bash
# Map two files and print a reportinfermap map crm_export.csv canonical_customers.csv
# Map and save the config (Python: --save, TS: -o)infermap map crm_export.csv canonical_customers.csv -o mapping.json
# Apply a saved mapping to rename columnsinfermap apply crm_export.csv --config mapping.json --output renamed.csv
# Inspect the schema of a file or DB tableinfermap inspect crm_export.csvinfermap inspect "sqlite:///mydb.db" --table customers
# Validate a saved config against a sourceinfermap validate crm_export.csv --config mapping.json --required email,id --strict

Config reference

Both packages accept an engine config (scorer weight overrides + alias extensions). Python uses YAML, TypeScript uses JSON; the shape is identical.

yaml
# Python: infermap.yamldomains:  - healthcare  - financescorers:  LLMScorer:    enabled: false  FuzzyNameScorer:    weight: 0.3aliases:  order_id:    - order_num    - ord_no
json
// TypeScript: infermap.config.json{  "scorers": {    "LLMScorer":       { "enabled": false },    "FuzzyNameScorer": { "weight": 0.3 }  },  "aliases": {    "order_id": ["order_num", "ord_no"]  }}

See infermap.yaml.example for a full annotated reference.

Documentation

Author

Ben Severn

License

MIT

來源:README.md,提交 b1bcee5

工具

0
SourceWeft 尚未讀取此伺服器的工具。

版本歷史

1
  1. v0.7.0最新Sep 16, 2026

評分

已滿足適用檢查項的 85%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分