☰
ai-job-search 薪酬基准工具(Salary Benchmark Tool)完全指南:从 Excel 数据到模糊匹配查询
2026/9/30 7:30:00 网站建设 项目流程
  • AI 应用
  • AI 技能

【免费下载链接】ai-job-search

The job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.

项目地址:https://gitcode.com/GitHub_Trending/ai/ai-job-search
点击查看免费下载

本文是 ai-job-search 项目内置薪酬基准工具(salary_lookup.py)的实战指南。该工具在/apply求职流程中承担"薪酬对标"职责:把招聘岗位所在公司的薪酬水平,与你自建的薪资基准数据做对比,帮助你在简历筛选与薪资谈判前掌握市场行情。读完本文,你将掌握salary_data.json数据格式的全部字段与约束、三种数据导入方式(手写 JSON / Excel 转换 / 逐步研究)、全部命令行参数的用法,以及底层模糊匹配算法与数据校验器的实现原理。

一、工具定位:可选的薪酬对标步骤

薪酬查询工具(salary_lookup.py)的作用,是将公司薪酬与你自己数据中的基线进行对比。它被集成在/apply工作流中,用于展示"某家公司的薪酬与市场水平相比如何"。

该工具是可选的:如果你没有薪酬数据,/apply流程中的薪酬步骤会被直接跳过,不影响其他求职功能。项目文档 README.md 明确写道:薪酬工具适用于你提供的任何薪酬数据(工会统计、Glassdoor 导出、个人调研等);若没有数据,薪酬步骤即被省略。在 SETUP.md 的安装向导中,薪酬基准被列为可选的第 5 步,同样是"跳过即省略"的语义。

二、工作原理:一份 JSON 数据 + 一个模糊匹配引擎

工具读取仓库根目录下的salary_data.json文件,其中包含公司薪酬基准数据。它使用模糊匹配按公司名查找,能够处理丹麦语/北欧字符(ø、æ、å 等)、法律后缀(A/S、ApS 等)以及常见的拼写变体。

从源码结构看,salary_lookup.py 的匹配管线分为三个可复用的标准化环节(见normalize、anglicize、extract_core_words三个函数):

  1. normalize(归一化):统一小写、去除空白,并按STRIP_PATTERNS规则剔除法律后缀与噪音词,包括A/S、ApS、I/S、P/S、K/S、IVS、AMBA/A.M.B.A.(带点写法)、括号内容(如(VG))、地域词(Danmark、Denmark、Scandinavia、Nordic)、通用词(Group、Holding)以及逗号后的子实体描述(salary_lookup.py 中STRIP_PATTERNS定义)。
  2. anglicize(英文化):按SPELLING_VARIANTS映射表把丹麦语字符替换为英语等价形式:ø→o、æ→ae、å→aa、ö→o、ä→ae、ü→u,从而让Mærsk与Maersk、Ørsted与Orsted能够互相命中。
  3. extract_core_words(核心词提取):再次剔除噪音后,提取出长度大于 1 的单词集合,用于词重叠评分。

匹配评分由match_score()计算,得分区间 0~100,search_company()只保留得分 ≥ 30 的结果并按相关度降序排列(salary_lookup.py)。评分层级大致如下(可由 tests/test_salary_lookup.py 中的用例印证):

匹配情形分值
归一化后完全相等(大小写、后缀不影响)100
英文化后完全相等(如OrstedvsØrsted)85
英文化后互为子串、或短词与核心词重叠75
归一化后互为子串80 + 长度比×10
多词重叠(按覆盖比例加权)30 ~ 70
无任何重叠0

配套的单元测试覆盖了这些分支:精确匹配返回 100(含MærskvsMærsk A/S、Arla Foods A.M.B.A.vsArla Foods amba)、短查询IBM命中IBM Corporation、Maersk命中Mærsk A/S、无关名称ApplevsVestas Wind Systems返回 0,以及城市过滤的大小写不敏感与英文化匹配(kobenhavn命中København)。

城市过滤

--city参数会做二次过滤:查询城市需出现在条目城市字段中(大小写不敏感),且同样支持英文化匹配;不满足即跳过该条目(见 salary_lookup.py 中search_company的城市判断逻辑)。

三、数据格式:salary_data.json完整说明

工具期望salary_data.json具备如下结构(该示例同时来自 tools/README_SALARY_TOOL.md 的官方模板):

{ "metadata": { "source": "My Union Statistics 2025", "index_baseline": 100, "index_label": "Index", "baseline_description": "Index 100 = median salary for private sector" }, "companies": [ { "company": "Novo Nordisk A/S", "city": "Bagsværd", "categories": { "all_employees": { "count": 500, "index": 108.5 }, "engineering": { "count": 120, "index": 112.3 } } }, { "company": "Ørsted A/S", "city": "Fredericia", "categories": { "all_employees": { "count": 200, "index": 105.2 } } } ] }

字段说明

  • metadata.source:数据来源说明(仅作参考,如 "My Union Statistics 2025")
  • metadata.index_baseline:基线数值,例如索引型数据为 100;若为 0 则表示直接展示绝对值(不计算百分比差)
  • metadata.index_label:输出表格中索引列的列名标签
  • metadata.baseline_description:基线的人性化解释文字,会打印在输出表格下方
  • companies[].company:公司名称(必填,非空字符串)
  • companies[].city:城市/地点(可选,用于--city过滤)
  • companies[].categories:具名薪酬类别,每个类别包含count和/或index

数据格式支持任意基于指数或绝对值的薪酬数据,例如:指数 100 = 中位薪酬(越高越好)、你所在币种的绝对薪酬值、或任何你想追踪的自定义指标。index甚至可以是字符串(如隐私保护的"private"),输出时原样显示而不会崩溃(tests/test_salary_lookup.py 的test_text_index_does_not_crash验证了这一点)。

输出表与"vs Baseline"列

当命中公司后,format_entry()会渲染一张对齐的表格(salary_lookup.py),列包括 Category、Count、Index 列与vs Baseline列。百分比差的计算公式为:((index - baseline) / baseline) × 100,正数带+号;当index_baseline为 0 时视为绝对薪酬模式,不显示百分比(测试用例test_format_entry_with_zero_baseline断言不含%)。此外:

  • 类别名中的下划线会转为空格并做标题化显示(all_employees→All Employees);
  • 若某类别只有count而没有index,其指数列显示为N/A*,并在表格下方打印脚注* N/A = Too few employees to publish (privacy)——即"员工人数过少,出于隐私不予发布"。脚注只在确实存在被抑制行时才打印(tests/test_salary_lookup.py 用两个用例分别验证了"无抑制行不打印脚注"和"有抑制行必须打印脚注")。

四、数据导入的三种方式

方式 A:手动创建salary_data.json

按第三节的格式手写文件即可,数据可来自任何渠道:工会统计、Glassdoor、薪酬调研、行业人脉信息或个人研究。

方式 B:从 Excel 转换(推荐用于批量数据)

如果你已有 Excel 格式的薪酬数据,使用仓库自带的转换脚本 tools/convert_salary_excel.py:

pip install openpyxl python3 tools/convert_salary_excel.py path/to/salary-data.xlsx \ --source "My Salary Data 2025" \ --baseline 100 \ --baseline-desc "Index 100 = median salary"
  • 在 Windows 上,若 Python 以py暴露在 PATH 中则用py;若系统用python而非python3,请相应替换示例命令。
  • 默认输出到仓库根目录的salary_data.json;也可用--output <路径>指定输出文件。
  • 转换器会自动探测 Excel 布局:
    • 查找 "Company"/"Firma" 列(也识别 virksomhed、employer、arbejdsgiver 等变体)与可选的 "City"/"By" 列(也识别 kommune、location、sted 等,见 tools/convert_salary_excel.py 的COMPANY_PATTERNS与CITY_PATTERNS);
    • 其余列视为薪酬数据,并自动配对 count/index 列(如 "Antal alle" 与 "Lønindeks alle" 会被归入同一类别alle);无类别词的裸 "Count"+"Index"(丹麦语 "Antal"+"Lønindeks")会归入默认类别all_employees,保证单类别布局也正确输出成一行(tests/test_convert_salary_excel.py 中BareCountIndexPairingTests覆盖该场景)。
  • 转换器内置多项防错保护(均有测试佐证):
    • 表头自动定位:会在前 10 行内寻找同时含公司列与城市/计数/指数列的表头行;无交叉佐证时回退到"任一单元格提及公司词"规则。丹麦工会统计导出文件常见的标题/引用行(如 "Kilde: … opdelt efter arbejdsgiver…")不会被误判为表头(对应 issue #414 的回归测试);
    • 数字区域解析:支持欧洲/美国两种千分位与小数点写法(1.234,56与1,234.56都能正确解析),但对单分隔符的歧义写法(如1,234、1.234)采取"宁可跳过、绝不猜错"策略,避免产生 1000 倍误差的薪酬值;丹麦语字符串单元格(如"12,0"、"108,5")也能正确转为数值;
    • 噪音列排除:自由文本列(如 "Notes")与标识符列(如 "Id"、"personnummer")不会被当作薪酬类别;
    • 多工作表支持:逐个解析所有 sheet 并合并输出(tests/test_convert_salary_excel_integration.py 中真实工作簿往返测试覆盖了多 sheet 与元数据写入)。
  • 转换完成后,metadata.index_label固定为"Index",source缺省使用 Excel 文件名(不含扩展名),baseline_description缺省为"Index <baseline> = baseline"。

方式 C:从研究积累起步

从一个空模板开始,随着调研逐步补充公司条目,例如使用绝对值模式:

{ "metadata": { "source": "Personal research", "index_baseline": 0, "index_label": "Monthly salary (DKK)", "baseline_description": "Approximate monthly salary before tax" }, "companies": [ { "company": "Example Corp", "city": "Copenhagen", "categories": { "entry_level": { "index": 42000 }, "senior": { "index": 55000 } } } ] }

注意此处index_baseline: 0表示绝对薪酬模式——输出时直接显示数值而不计算百分比差,index_label可自由命名为 "Monthly salary (DKK)" 之类的业务含义标签。

五、命令行用法

主程序支持五个调用形态(salary_lookup.py 的main()中定义):

python3 salary_lookup.py "Novo Nordisk" python3 salary_lookup.py "Ørsted" --city "Fredericia" python3 salary_lookup.py "COWI" --json python3 salary_lookup.py --list-all python3 salary_lookup.py --validate # pre-flight check your salary_data.json

各参数说明:

参数作用
company(位置参数)要搜索的公司名;缺省且未使用其他模式时打印帮助信息并退出
--city <名称>按城市过滤结果(大小写不敏感,支持丹麦语字符英文化匹配)
--json以 JSON 数组输出命中结果(ensure_ascii=False,保留原始字符)
--list-all列出数据集中所有公司名(含城市,若有)
--validate校验salary_data.json并输出报告后退出,不执行查询

--validate的行为细节:无问题输出OK - no issues found.并以退出码 0 结束;有问题时分Errors(硬错误,退出码 1)与Warnings(可用性问题但能正常工作,退出码 0)两类报告(salary_lookup.py 的print_validation_report)。典型检查项包括:顶层必须是对象、companies必须是列表、公司名必填且非空、city/categories为对象时类型正确、类别必须是含count和/或index的对象、count必须是数字、重复公司名仅记为警告(tests/test_salary_lookup.py 的ValidateDataTests系列用例逐一验证)。

无结果的提示

当搜索无命中时,工具会提示尝试更短或不同的名称,并提醒数据集中公司名可能包含 "A/S"、"ApS" 等法律后缀;若使用了--city过滤,还会附加提示被城市过滤排除。

六、数据隐私与安全设计

  • 数据文件不入库:salary_data.json已被 .gitignore 排除。你的薪酬数据可能涉及专有或保密信息,因此刻意不纳入版本控制;SETUP.md 也提示应将真正敏感的文件(tracker、薪酬数据、documents/、申请归档等)保存在本地,避免推送到公开 fork。
  • 缺失文件的友好降级:若salary_data.json不存在,salary_lookup.py会打印包含完整指引的错误信息(提示参阅 tools/README_SALARY_TOOL.md),并以退出码 1 结束;/apply工作流随后自动跳过薪酬基准步骤。
  • JSON 解析错误无堆栈:非法 JSON 会报告具体行列号(如invalid JSON at line N, column N),不打印 Python 堆栈,便于用户自查文件(tests/test_salary_lookup.py 的test_load_data_reports_json_parse_errors_without_traceback)。
  • UTF-8 输出强制:main()入口处通过_force_utf8_output()将 stdout/stderr 强制重配为 UTF-8,避免在 Windows 管道输出(默认 ANSI 代码页 cp1252)时因公司名、职位名等含丹麦语字符或非拉丁字符而抛UnicodeEncodeError。tests/test_tools_utf8_output.py 端到端验证了波兰语、西里尔文、中日韩字符均能干净地通过两个工具输出。

七、数据校验与容错边界

validate_data()是查询前的强制关卡(load_data()= 读取 + 解析 + 校验),它把畸形数据挡在查询之前。从collect_validation_issues()的返回设计看,校验器刻意区分两类问题:

  • Errors(硬错误):会导致查询崩溃或输出错误,如顶层不是对象、companies不是列表、类别值不是对象、count非数字等——--validate遇到即退出码 1;
  • Warnings(软问题):仍然可用,如重复公司名——报告但退出码 0。

值得一提的是容错细节:--validate允许metadata或categories显式为null(与省略等同),而查询渲染路径也必须对null不崩溃——format_entry()内部对 metadata 与 categories 做了空值兜底,并把条目中除company/city/categories外的其他 dict 字段视为类别兜底渲染(tests/test_salary_lookup.py 的NullShapeEndToEndTests验证了"通过 --validate 后查询也能正常渲染"的完整链路)。

八、小结:在求职流程中的使用建议

推荐的最小落地路径:先在 SETUP.md 完成基础安装(项目要求 Python 3.10+),再按需选择一种方式建立salary_data.json(工会统计 Excel 转换最省力,个人调研手动维护最灵活),随后运行python3 salary_lookup.py --validate做一次预检,确认数据合法后即可让/apply流程自动执行薪酬对标。日常使用中,--city可区分同一公司在多地的薪酬差异,--json便于脚本化集成,--list-all可快速浏览数据集全貌。薪酬数据始终留在本地、不入库,既保护了隐私,也让这套基准完全由你掌控。

  • AI 应用
  • AI 技能

【免费下载链接】ai-job-search

The job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.

项目地址:https://gitcode.com/GitHub_Trending/ai/ai-job-search
点击查看免费下载

相关推荐

上一篇:终极指南:如何用一套键盘鼠标无缝控制多台电脑
下一篇:联想拯救者BIOS高级设置一键解锁工具:3分钟开启隐藏功能终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询