
OpenHire v0.2 是在我自己的求职工具链里长出来的东西。它做的事情一句话就能说清把宇树、优必选、智元、傅利叶、云鲸、石头、埃斯顿、汇川、遨博、越疆、节卡这 11 家国内机器人公司在官网招聘页、公众号和主流招聘平台上公开发布的职位整理成一份结构化的 JSON 职位库再通过 MCP 协议挂到 Claude Code 上让 Claude 在终端里用自然语言就能直接搜索、筛选、比对岗位。如果你正在刷机器人行业的坑位又恰好是 Claude Code 的重度用户这套东西能帮你把每天开十个网页找 JD 的时间压缩下来。这篇文章会从需求拆解、数据结构、MCP 实现到实测案例完整过一遍顺便把这些天踩过的坑都交代清楚。1. 为什么会有 OpenHire一个让人烦躁的职位信息源问题1.1 机器人公司的招聘信息到底有多碎先说一个所有找过机器人岗位的人都会遇到的真实场景。宇树的招聘信息散落在官网招聘页、微信公众号推文和 BOSS 直聘上优必选的岗位可能在官网、牛客讨论区和猎聘同时挂着而且各渠道的 JD 内容还经常不一致。公众号推文里的岗位会写得比较丰满有团队介绍、技术栈、项目背景但官网岗位列表往往只有一句话概括招聘平台上的薪资范围可能比官网明显却不一定是最新版本。这种情况在和互联网大厂的招聘体验对比时差距尤其明显。大厂基本都有统一的招聘官网岗位状态、筛选流程、投递记录能在一个系统里跟踪。但机器人行业里有相当一部分公司尤其是硬件属性重、创始人背景偏学术的团队招聘页面的维护优先级并不高。有些公司的招聘信息只在公众号文章里以“急招”的形式闪过一次过几天再去看已经删了有些岗位在 BOSS 直拒上的发布时间和官网完全对不上。我一开始的做法是手动维护一个岗位清单看见一条记一条记录公司、岗位、链接、城市、薪资范围。这个做法在只有五六家公司的时候还行但一旦你想横向对比同类型岗位比如比较两家公司在 SLAM 方向上的 JD 差异整个人就会陷入复制粘贴地狱。更麻烦的是手动维护的清单没有更新机制你今天看到的岗位信息是两周前的快照等你真正去投递的时候对方早招满了。1.2 从静态清单到 Claude 可查OpenHire v0.2 解决的核心问题所以 OpenHire v0.1 时的形态就是一份 Markdown 表格加一个 JSON 文件内容是我人工整理的少量公司职位。说实话v0.1 更像是给自己用的笔记发布出去之后别人问“这个清单怎么用”我只能说“你打开 JSON 自己看”。这显然不够因为职位清单只是原料真正的价值在于怎么让人高效地消费这些原料。v0.2 的核心变化是让 Claude 可以直接查这份职位库。这里的“Claude”主要指 Claude Code也就是我在终端里常用的编码代理工具。我把职位库做成一个 MCP server 挂在 Claude Code 上Claude 就能通过 search_jobs 这类工具实时读取职位数据。你不需要自己在终端里翻文件、猜字段、写查询脚本你只需要用自然语言问“看看宇树科技在杭州招哪些跟运动控制相关的岗位”Claude 会自己去调用工具、聚合结果、按你的要求整理成表格或者摘要。这个转变很关键。过去职位信息消费的最小单位是一条 JD你得一条条打开、阅读、判断现在最小单位变成了“一个查询需求”让 Copilot 式的交互直接作用在招聘数据上。OpenHire v0.2 真正解决的问题不是“又多了一个爬虫”而是把分散、异构、非结构化的招聘信息变成了 Agent 可以理解和操作的结构化数据入口。2. 职位数据是怎么采集、清洗成 11 家公司的结构化信息的2.1 11 家公司的覆盖名单和选择逻辑先放名单这 11 家是我在春节前确定的覆盖范围宇树科技、优必选、智元机器人、傅利叶智能、云鲸智能、石头科技、埃斯顿、汇川技术、遨博智能、越疆科技、节卡机器人。没有选满整个行业是因为这个版本我更看重“数据可用性”而不是“数量”。名单的筛选标准有三条第一公司有明确的公开招聘渠道官网招聘页或者公众号公开岗位这样采集的数据能追溯来源第二岗位数量足够多太少的话接进 Claude 里没有意义一查全是空结果第三覆盖主流技术方向和职能分布既要有人形机器人相关的算法岗位也要有 SLAM、机器人操作系统、机械结构、嵌入式、供应链和产品经理这类岗位不然用户来查的时候会感觉范围太窄。按这个标准宇树和优必选是必须要进的。宇树在人形和四足机器人方向的岗位结构很有代表性优必选则覆盖了人形机器人从研发到商业化落地的整条链。智元和傅利叶近两年在具身智能方向放出的岗位密度很高云鲸和石头是消费级机器人的典型样本。埃斯顿、汇川、节卡、遨博、越疆这几家在工业机器人和协作机器人领域有比较完整的岗位体系加上它们整个职位库才不至于变成清一色的“人形机器人专场”。这里要说明一下这个名单并不代表“国内做机器人的前 11 强”它是我认为在当前阶段具有代表性的一个样本集。OpenHire 的架构本身不绑死这些公司后面想加公司直接往数据目录里丢一个新的 JSON 或者配置一个新的采集源就行。2.2 职位库的字段设计为什么这些字段缺一不可数据结构是个容易被低估的环节。很多个人项目做到后期最大的坑不是功能没实现而是数据字段没有统一导致 Agent 在查询的时候无法正确理解。OpenHire v0.2 的职位数据按一条一岗的方式组织核心字段包括字段示例说明company宇树科技公司名称统一用全称方便聚合job_title高级运动控制算法工程师岗位名保留原始招聘页面的写法city杭州/深圳工作地点双地点用“/”分隔category运动控制岗位分类用于语义筛选salary25K-45K·14薪原始薪资描述可能为空source官网/BOSS/猎聘信息来源渠道urlhttps://...原始 JD 链接保证可回溯posted_at2025-01-20抓取时间方便判断时效description一段岗位描述保留原文中的核心 JD不自行摘要requirements一段任职要求同上尽量原文为什么字段要这样设计几个容易被忽视的点第一source 字段非常重要因为同一条岗位可能在不同平台上挂了不同版本保留渠道可以帮你发现信息差异第二category 字段虽然在爬取时无法直接获得但它是让 Claude 高效工作的关键我用了一个半自动的规则加人工复核的方式把岗位归入运动控制、机器人操作系统、感知算法、机械结构、嵌入式开发、产品、销售、供应链等十几个大类第三salary 这类字段我选择保留原始描述而不强行解析成数字因为不同公司写薪资的方式差别太大有的写“20-40K·13薪”有的只写“面议”强行结构化反而会制造错误。2.3 采集过程与合规红线采集过程我坚持一个原则只采集公司或招聘平台公开发布的求职信息绝不绕过登录、验证码、访问控制也不去碰任何需要通过爬虫对抗才能拿到的数据。具体到操作层面我用了一个非常轻量的脚本通过读取公司官网招聘页和招聘平台公开搜索结果的入口拿到岗位列表后再对齐到 URL、发布时间、岗位描述这几个关键字段。运行频率不高基本是每周手动触发一次为了给每条数据打上抓取时间。这里想多说一句国内招聘信息更新节奏和海外不太一样很多公司会更倾向于在内部推荐群、HR 朋友圈、“急招”海报上发布岗位这些信息是采集不到的。所以 OpenHire 的定位从来不是全量职位数据库而是“公开渠道可见的职位快照”。它最大的价值不是让你找到所有岗位而是让已经被公开出来的那部分信息能够被高效检索和利用。合规方面我只放公开信息并且本来就会在 README 里提醒使用者最终投递前一定要回到官网或招聘平台核实岗位最新状态。清洗数据的过程则比较笨。我写了几条规则去去重比如同一家公司的同一个岗位标题在不同渠道都出现时以官网版本为准再比如把“北京/上海/深圳”这种多地点字段统一成“/”分隔还有一些明显是重复发布的相似岗位我会保留信息更完整的版本。每天大概要花半小时到一小时做人工复核整个过程没什么高深技术但恰恰是这一步决定了 Claude 给出的答案靠不靠谱。3. 让 Claude 直接搜的核心实现MCP server 的方案与配置3.1 为什么不能直接把 JSON 塞给 Claude最早有人问过我既然职位库就是一个 JSON 文件为什么不直接把文件内容粘到 Claude Code 的对话里让它自己读这个问题看起来合理实际用起来会发现三条硬伤。第一是 token 浪费。这个职位库现在已经有小几百条岗位记录每条带 description 和 requirements加起来是一大坨文本。每次对话都把这坨文本塞进上下文Claude 很快就会被无关信息淹没明明你只想知道某一家公司的一个岗位它却得从几百条记录里大海捞针。第二是更新问题。职位库是每周更新的快照如果你是通过复制粘贴喂给 Claude那就等于每次更新都要重新粘贴一次这个工作流不可持续。第三是查询不灵活。直接塞文本Claude 能做的事情很有限你不能让它“对比宇树和优必选在 SLAM 岗位上的差异”因为文本是一口气灌进来的缺少一个可以按参数检索的外层。所以 v0.2 我选择了 MCPModel Context Protocol模型上下文协议这个标准方案。你可以把 MCP 理解成给 Claude 装了一组外挂工具的标准接口Claude Code 原生支持通过 MCP 调用外部服务。我要做的事情很简单写一个小程序把 search_jobs、get_job_detail 这类操作封装成工具然后告诉 Claude Code 这个 MCP server 的启动方式。之后 Claude 就知道它有“搜职位”这个能力需要的时候会自动调用。3.2 OpenHire MCP server 的核心结构我用 Python 写了这个 MCP server核心逻辑非常薄所有数据从 JSON 文件加载到内存每次查询就是一次过滤和排序。选择用 Python 而不是 Node.js纯粹是因为我处理数据的习惯路径在 Python 这边数据清洗、字段标准化这些活儿用 pandas 或者纯标准库都顺手。代码结构简化后大概是这样的# openhire_server.py简化示例 import json from pathlib import Path from mcp.server.fastmcp import FastMCP mcp FastMCP(openhire) DATA_FILE Path(__file__).parent / data / jobs.json def load_jobs(): return json.loads(DATA_FILE.read_text(encodingutf-8)) mcp.tool() def search_jobs( company: str , keyword: str , city: str , category: str , limit: int 20, ) - str: 在 OpenHire 职位库中搜索机器人公司岗位。 Args: company: 公司名称如 宇树科技、优必选 keyword: 岗位关键词如 运动控制、SLAM、嵌入式 city: 城市如 杭州、深圳 category: 岗位分类如 算法、机械、产品 limit: 返回条数上限 jobs load_jobs() results [] for job in jobs: if company and company not in job.get(company, ): continue if city and city not in job.get(city, ): continue if category and category not in job.get(category, ): continue if keyword and keyword.lower() not in (job.get(job_title) job.get(description, ) job.get(requirements, )).lower(): continue results.append(job) if len(results) limit: break return json.dumps(results, ensure_asciiFalse, indent2) mcp.tool() def get_companies() - str: 返回当前职位库覆盖的公司名单。 companies sorted(set(job[company] for job in load_jobs())) return json.dumps(companies, ensure_asciiFalse)FastMCP 这个写法非常直白每个函数加一个mcp.tool()装饰器就是一个工具节点。函数签名里的 docstring 会被 Claude 用来理解工具用途和参数含义所以写得越清楚越好。search_jobs 这个函数内部做的是纯粹的 Python 过滤没有任何花哨的检索逻辑因为当前数据量根本不需要上全文索引字符串匹配已经足够。此外我还写了一个 get_job_detail 工具根据 job_id 返回单条职位的完整字段这样 Claude 在筛选完岗位后可以展开看某一条的原始 JD不至于在搜索结果里看到一堆截断文本。3.3 从 clone 到在 Claude Code 里查询接下来是实际接入步骤。OpenHire 属于本地运行项目所有工具都跑在本机不会把职位数据上传到额外服务器Claude Code 通过 MCP 访问的是你自己的本地进程。整体配置过程如下# 1. 克隆项目并创建 Python 虚拟环境 git clone https://github.com/yourname/openhire.git cd openhire python3 -m venv .venv source .venv/bin/activate # 2. 安装依赖 pip install -r requirements.txt # 3. 把 MCP server 注册给 Claude Code # 注意具体命令因 Claude Code 版本不同可能有差异以项目 README 为准 claude mcp add openhire -- python /绝对路径/openhire_server.py # 4. 验证注册结果 claude mcp list看到 openhire 出现在 MCP server 列表里说明注册成功。之后正常启动 Claude Code就可以用自然语言查询了。配置这一步有几点需要注意。路径尽量写绝对路径用相对路径经常会因为工作目录不一致导致 server 起不来。第二如果你机器上有多个 Python 环境启动命令里的 python 最好指向虚拟环境里的解释器否则可能装了一堆依赖却找不到包。第三如果你在 Windows 上操作命令里的 python 路径大概率会跟 macOS/Linux 不一样建议在 README 里把 Windows 的示例也放出来。总的来说MCP 配置本身不复杂卡住的点基本都是环境问题。3.4 Claude 是怎么理解“直接搜”的接入完成后Claude Code 在会话里会自动感知到 openhire 这个 MCP server 提供的工具。当用户提问时Claude 会把问题映射到对应的工具调用上。比如你说“查一下优必选在深圳招哪些岗位”Claude 会调用 search_jobs填入 company优必选、city深圳拿到结果后再整理归纳给你。这个过程中最有意思的是Claude 会根据你追问的粒度决定调用参数。如果你说“看看有哪些公司被收录了”它会选择 get_companies 而不是 search_jobs如果你说“找找杭州的 SLAM 岗位”它会同时传 city 和 keyword 两个参数。也就是说OpenHire 的价值不是实现了某种复杂的推荐算法而是给 Claude 提供了一个边界清晰、字段统一的数据查询接口让模型能基于这个接口做二次分析。4. 我实测下来的三种典型查询方式4.1 案例一搜“宇树科技在杭州的运动控制岗位”第一种也是最基础的用法就是按公司加关键词定向搜索。我在 Claude Code 里直接输入用 openhire 工具查一下宇树科技招的运动控制相关岗位列出岗位名称、城市和薪资。Claude 随即调用 search_jobs返回一部分示意数据我这里展示的是经过脱敏和格式化的结果实际每次抓取快照会有差异公司岗位名称城市薪资宇树科技运动控制算法工程师杭州25K-45K·15薪宇树科技人形机器人运动规划工程师杭州30K-50K·14薪宇树科技机器人调度算法工程师运控方向杭州25K-40K·14薪输出之后 Claude 会自行总结比如“这三条岗位都集中在杭州前两个偏人形机器人运动规划第三个偏运控系统集成”。如果你还想看某一条的详细 JD直接说“展开第一条”Claude 就会调 get_job_detail 把完整要求贴出来。这类查询的价值在于Claude 把本来需要一个个页面点开的工作变成了表格输出而且所有结果都带着 URL方便你手动核验。我不会拿 Claude 的输出当最终答案但它足够帮我做第一轮粗筛。4.2 案例二跨公司对比 SLAM 算法工程师岗位第二个场景更体现出 OpenHire 的差异化。过去想跨公司比较同一个岗位方向比如 SLAM 算法工程师在不同机器人公司的要求有什么差异你需要同时开着七八个招聘页面人工比对标题、职责、任职要求。这个过程极其容易被细节淹没因为每个公司的 JD 长度、措辞和侧重点完全不一样。现在我的操作是直接问从 openhire 岗位库里帮我对比一下当前几家主要公司 SLAM 方向的岗位按公司分组列出工作地点、薪资和任职要求里的共同点和差异点。Claude 会调用 search_jobskeyword 传“SLAM”然后对返回结果做二次加工。示意输出大致是宇树科技的 SLAM 岗位更偏人形机器人环境感知要求熟悉视觉惯性导航系统对部署到嵌入式平台的经历很看重。石头科技的 SLAM 岗位偏向扫地机器人建图和定位强调大规模量产项目的落地经验。优必选的 SLAM 岗位则结合了人形机器人的多传感器融合对 Linux 和 C 的工程能力要求很硬。这种对比要是让我自己看至少得一小时Claude 基于结构化数据几分钟就整理出来了。当然它的结论基于职位描述原文不会凭空捏造但你也得意识到JD 和真实工作内容之间通常有一定差距所以对比结果只能作为参考不能当成“这家公司一定这样”的事实。4.3 案例三让 Claude 直接生成投递邮件和工作底稿职位筛选完之后真正花时间的环节是写投递邮件、整理技术栈对照表、准备面试问题。这类任务其实和职位数据强相关Claude 在拿到岗位要求后完全可以辅助完成。我的实际用法是选定一个岗位之后直接对 Claude 说挑一个我觉得最匹配的岗位以我的背景3年机器人感知方向经验熟悉 C 和 Python写一封简洁的投递邮件并在邮件正文里把岗位要求和我经验的匹配点列出来。Claude 会基于该岗位 description 和 requirements 生成草稿我再根据实际情况修改。另一个很实用的操作是让 Claude 对同一家公司的多个岗位生成一个“技能交集”梳理看看自己当前的技术栈最贴近哪一类岗位。这也是为什么要让职位数据保持结构化——只有数据可查询、可对比这些上游的 Agent 工作流才可能成立。5. 常见问题与避坑记录5.1 职位数据过期导致链接失效这是 OpenHire 最容易遇到的问题。招聘信息的时效性很强一个岗位今天还在下周可能就下架了。我在刚开始测试时就发现Claude 返回的岗位链接偶尔点开会看到“该职位已下线”原因是抓取快照和实际发布状态之间有时间差。解决方案是在 schema 里强制带上 posted_at 字段也就是抓取时间。同时工具返回结果时Claude 会习惯性附上“数据抓取时间”的提示提醒使用者自行核实。如果你发现某个岗位已经失效不要慌先在官网招聘页确认最新招聘状态再看是否需要更新职位库数据。说到底OpenHire 提供的是“快照检索”不是“实时刷新”两者有本质区别。5.2 MCP server 起不来MCP 配置是大家问得最多的一个问题。常见现象是claude mcp list里 openhire 显示 abnormal或者 Claude 调用工具时报“工具不存在”。排查思路其实很简单现象可能原因处理方式server 启动失败Python 路径不对依赖没装进当前环境使用虚拟环境绝对路径启动重新 pip install工具列表为空MCP server 返回错误单独运行 openhire_server.py看有没有异常报错Claude 调用超时首次加载 JSON 数据较慢检查数据文件是否过大缩小 description 长度端口或 stdio 模式冲突多环境变量干扰确认 README 里推荐的启动方式避免混用实操中我一般先用命令行python openhire_server.py直接跑一遍确认程序本身没报错再去看 MCP 注册。MCP 的调试不太适合在黑盒里进行最好是先把 server 当作普通 Python 进程跑通了再接入 Claude Code排查成本会低很多。5.3 Claude 找不到工具或者工具权限受限另一个常见情况是 Claude Code 虽然加载了 openhire但在对话中明显没有调用工具而是直接猜测答案。这多半和自动批准策略有关Claude Code 对工具的调用可能需要你确认权限如果没有授权它会倾向于“空手回答”。解决办法是在 Claude Code 的配置里对这个 MCP server 开启自动批准或者在最开始对话时明确说“你可以调用 openhire 工具来查询”帮助 Claude 建立意图。尤其是我这种偏好轻配置的人每次都要手点确认会被打断思路所以我会把 openhire 的 tools 设置为 auto-approve。但要注意这只适用于你自己信任的本机工具不要对其他来源的 MCP server 盲开。5.4 这个工具能自动投简历吗很多人看到“让 Claude 直接搜”就会追问能不能让它直接帮我投我的回答很明确不能也不建议在 v0.2 里做。理由有三条。第一当前互联网招聘平台普遍有验证码、登录态、安全策略自动投递很容易触发风控对账号本身有风险。第二即使技术上能做投简历是一个非常需要“人参与”的动作你的求职意向、期望薪资、跳槽时机这些因素Agent 很难替你判断。第三从责任角度看让 AI 代替你投递公司 HR 收到的可能是一堆雷同的 AI 生成内容这对于任何一方的体验都是损害。所以 OpenHire v0.2 定位在一个合理的边界内帮你检索、筛选、对比、生成辅助材料但最终决策和投递动作一定是你自己完成。把所有环节都交给 Agent不是效率问题而是责任和能力边界问题。5.5 数据覆盖不全、更新节奏慢怎么办目前 OpenHire 的数据更新是半自动的脚本抓取加人工复核。11 家公司虽然已经有一定代表性但离“全量覆盖”还差得远。如果你发现某家公司没被收录或者某个岗位在职位库里找不到别急着否定这个项目这其实是数据源覆盖范围的问题。OpenHire 的设计里预留了扩展方式往数据目录里添加新的公司 JSON或者写一个新的采集脚本就能在下个版本纳入更多公司。对于我个人而言v0.2 的核心目标是把“结构化职位库 Claude 可查询”这条链路跑通而不是把所有公司一次性装进来。后续版本可能会加入公司维度的人才需求趋势分析比如按季度统计某家公司在算法、产品、供应链方向上的岗位数量变化让求职者能看出团队当下的投入重点。从我这些天的实际使用体验来看最打动我的并不是 Claude 帮我省了多少时间而是当职位信息变成结构化数据之后整个求职决策的前半段可以有更高的确定性。你不再需要凭记忆对比十几条 JD而是可以让 Agent 帮你把信息铺平、分类、找出差异再由你来做最后的判断。顺着这个思路往下走如果后续能接入更多公开公司甚至在 get_company_insight 里补充团队背景、融资阶段、技术栈信息这套东西的价值会再上一个台阶。不过那是 v0.3 的事了先把当前版本用起来比什么都重要。