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 分