Imported from LucioLiu/Loom-HR (
AGENTS.md). Install upstream withnpx skills add LucioLiu/Loom-HR. Copyright stays with the author.
AGENTS.md — 让 AI agent 自主上手「Loom HR」招聘自动化
这是给用 AI agent 来跑 / 教学 / 扩展本项目的人(和 agent 本身)看的上手地图。 读完你应能:起服务、看懂架构、知道 AI 层怎么接、加一个新岗位、找到扩展点、守住安全须知。 人类一页纸使用说明在
界面_伯乐驾驶舱/README_使用说明.md;不想碰命令行就双击仓库根目录的启动LoomHR.bat。
0 · 这是什么(30 秒)
一个有独立网页 UI(「伯乐驾驶舱」)的招聘全流程自动化产品——不是散脚本。在一个界面看招聘漏斗、点按钮触发自动化、用「岗位插槽(slot)」一键切换岗位、用 AI 做候选人判断。先吃透 BOSS 直聘一个平台。
- 后端:Node.js(内置
http/fs/child_process;日志走 SSE 免 ws)。 - 前端:vanilla HTML/CSS/JS + SVG,零构建、不引 CDN、离线可跑。
- AI 层:默认调本机
claude -p(零 key);可选绑自己的 provider 走 CCR。 - 判定口径是数据、不是代码:收谁/跳谁的标准全在 slot 的 JSON/md 里(SSOT),改口径只改数据文件。
- 对外触达默认关闭:
settings.outreachEnabled默认false——打招呼/要简历默认任何模式都发不出去;用户在设置页经风险确认可开启(开启后限流+留痕,见 §6)。
⚠ 公开 Demo 定位:仓内自带一个全虚构的演示卡槽
_demo岗位+ 8 个『演示-XXX』假候选人(npm run seed-demo注入 loom.db + 阶段事件,分布漏斗各阶段呈递减形),clone 即可跑通「看候选人 → AI 初筛 → 打分 → 看板流转」链路,不依赖真实 BOSS 采集、不发任何真消息。真采集是另一条路(见 §6),公开演示不需要。
1 · 怎么启动(公开 Demo 最短路径)
前置:本机 Node ≥ 20.16(package.json engines 要求;开发机实测 Node v24 / npm 11 可跑)。
cd 界面_伯乐驾驶舱
npm install # 拉 better-sqlite3 / imapflow / mailparser / mammoth / pdf-parse(约 100MB,预编译产物,无需 VS 编译链)
npm run seed-demo # 把 demo/candidates.demo.json 复制成 data/_demo岗位/candidates.json(全虚构『演示-XXX』)
npm start # = node server.js,默认端口 8780
浏览器开 http://localhost:8780 → 顶栏卡槽默认是「示例·全栈工程师(公开 Demo)」→ 主页漏斗 8 个演示候选人分布各阶段(曾到达 8/7/4/2/1/1/1 递减形)、各格可下钻 → 可点 AI 初筛 / 一键打分 / 简历详情 / 看板拖卡。
- 模式默认 🟢预演(dryrun):真读真判、不写不收不发。
- 端口被占:
PORT=8888 npm start(bash)/$env:PORT="8888"; npm start(PowerShell)。 - 不配 AI 也能起界面与看数据,只是 AI 初筛/打分不可用(见 §3)。
- 起不来先看终端那行
Loom HR · 招聘 on http://localhost:PORT,没出现说明端口冲突或依赖没装。
2 · 架构地图(关键目录与职责)
项目根 = 本仓库。主程序在子目录 界面_伯乐驾驶舱/(npm 工程在这层,不在仓库根)。
招聘自动化/ ← 仓库根(本 AGENTS.md 在这)
├─ AGENTS.md ← 你在读的这份
├─ .gitignore ← 焊死 PII/登录态/密钥/大二进制 不进仓
├─ 界面_伯乐驾驶舱/ ← 🟢 主程序(后端+前端+卡槽+数据)
│ ├─ server.js ← Node 入口;HTTP/JSON API;编排引擎+AI;对外发送安全锁(outreachUnlocked)在这
│ ├─ package.json ← deps + scripts(start / seed-demo / install-semantic)
│ ├─ web/ ← 前端:index.html / app.js / style.css(漏斗/初筛/弹窗/SSE日志)
│ ├─ slots/ ← 🔑 岗位插槽(产品判定口径 SSOT,进 git)
│ │ └─ _demo岗位/ ← 公开 Demo 卡槽(全虚构,§4 讲怎么照它加岗位)
│ ├─ demo/candidates.demo.json ← Demo 候选人种子(虚构,进 git;seed-demo 读它)
│ ├─ seed_demo.js ← 一键灌 demo 数据脚本
│ ├─ config/settings.json ← 运行参数(activeSlot/mode/caps/delays…,进 git,无敏感)
│ ├─ data/ ← ⛔ 运行期数据(候选池/反馈/日志/judgment.db)·【.gitignore 焊死·防PII入仓】
│ ├─ ai_backend.js ← 「绑自己的AI」CCR 生命周期 + 隔离配置
│ ├─ judgment_db.js / judgment_vec.js← 判断力 RAG 知识库(FTS5 + 可选语义向量)
│ ├─ resume_parse.js / resume_field_parse.js / resume_vault.js ← 简历摄入/解析/原件存放
│ ├─ mail_intake.js ← 邮箱收简历(IMAP,默认关,只收不发)
│ ├─ stage_model.js ← 漏斗后段阶段流转(只追踪不自动推进)
│ └─ test_*.js ← 各模块自测(node test_xxx.js 直接跑)
├─ 内核_ai初筛/ ← AI 初筛内核(独立于 server,可单跑)
│ ├─ run_screen.js / screen.js ← 批量初筛主程序 + 评分卡渲染
│ └─ ai_bridge.js ← claude -p 主路径 + 评分桥兜底(PONG 探活)
├─ 引擎_BOSS推荐牛人自动收藏/ ← 裸 CDP 浏览器引擎(真采集;boss_*.js;连本机 9333 调试Chrome)
└─ SOP与卡槽_半自动化招聘全链路/ ← 半自动 SOP + 空白岗位卡槽模板
数据流(公开 Demo 路径):
data/<slot>/candidates.json(候选池)→ server assembleCandidates() 读取 → /api/candidates 喂前端 → 点「AI 初筛」/「一键打分」→ server spawn 内核_ai初筛(或 server 内联打分)调 claude -p 按 slot 的 评分卡.json 判定 → 结果落回 candidates.json[name].score + screen_result.json → 前端三色档(行/待定/不行)+ 简历详情。
候选池来源优先级(server.js assembleCandidates):本 slot data/<slot>/candidates.json → 引擎判定审计 boss_judge_audit.jsonl → 内核合成 fixtures(demo 兜底)。
3 · AI 层怎么接
判断/打分需要一个可用的 LLM。两条路,产品自动探活择路:
主路径(推荐·零 key):本机 claude -p
- 本机
claude login过、或装了长效 setup-token(claude setup-token,复用 Max 订阅)即可,不需要任何 API key / 环境变量。 - 探活:内核
ai_bridge.js探到/PONG/视为可用;探不到自动降级到评分桥(生成一段可复制的打分指令,粘给你会话里的 AI 跑,绕开 headless 鉴权坑)——所以即使claude -p不通,产品也不崩、只是改成半自动。 - Windows 坑:
claude是claude.cmd,spawn 需经 shell(代码已处理)。
备选路径(绑你自己的 provider):CCR(claude-code-router,可选依赖)
npm install会装@musistudio/claude-code-router(optionalDependency)。- provider key 不进 git:放本机
config/ai_backend_secret.json({ "apiKey": "...", "ccrApikey": "..." }),由ai_backend.js注入隔离的 CCR HOME,再经process.env.LOOM_AI_BACKEND=ccr让子进程走 CCR。 - 强/弱模型名分流走
settings.json的aiBackend块 →LOOM_MODEL_STRONG/WEAK环境变量。
环境变量清单:见 界面_伯乐驾驶舱/.env.example。注意⚠:产品不内置 dotenv 自动加载,它直接读 process.env;要用 .env 请 node --env-file=.env server.js(Node ≥20.6),或在 shell 里先 export。敏感凭据走 config/*_secret.json,不走 .env。
判断力 RAG(可选增强):默认零依赖关键词检索(本机可跑)。要开语义向量检索:npm run install-semantic(装 sqlite-vec + transformers,约 +400M),再设 LOOM_SEMANTIC_RAG=on。
4 · 卡槽 slots 怎么加岗位(核心扩展动作)
一个 slot = slots/<岗位id>/ 一个目录,装该岗位的全部判定口径。新建 slot 不用改代码——server 的 listSlots() 直接读目录名,放好文件、把 config/settings.json 的 activeSlot 指过去即可。
最快:UI 顶栏「+新建岗位」填需求表,自动生成画像/JD/评分卡/话术/筛选规则/RAG 种子 → 自动切到新岗。
手动(agent 友好):照 slots/_demo岗位/ 复制一份,改这些文件:
| 文件 | 作用 | 必填 |
|---|---|---|
manifest.json |
岗位元信息(name = 目录名、displayName、stage、boss职位匹配) |
✅ |
JD.md / 画像.md |
人读的岗位描述与画像 | 建议 |
评分卡.json |
🔑 机器可读严格评估卡——AI 初筛/一键打分/电话评估都吃这份(硬门槛→维度锚点→加减分→分档) | ✅ |
评分卡.md |
评分卡的人读镜像 | 建议 |
筛选规则.json |
BOSS 筛选面板勾选项 + 采集时硬卡正则(judge/xiao 块) | 真采集需要 |
话术.json |
触达话术(对外发送默认关闭时仅作草稿预演;用户开启真发后「要简历」字段会被真发) | 可选 |
redflag_vocab.json |
红旗/绿旗受控标签词表(供 RAG 聚类;🔴 严禁含年龄/院校/性别等受保护维度) | 建议 |
_rag/*.md |
判断知识库种子(tech-stack/negative-signals/phone-questions/judge-criteria);按 ## 二级标题切 chunk,可写 [tags: ...] |
建议 |
stage_docs/*.md |
各阶段 AI 辅助文档模板 | 可选 |
candidates 数据形态(data/<slot>/candidates.json,运行期生成、不进 git):
{ "candidates": [ {
"name": "内部唯一id", "realName": "显示名",
"salary": "30-45K", "base": ["上海","本科","在职-考虑机会","5-10年"],
"expect": "上海·全栈工程师", "advantage": "一句话亮点",
"tags": ["Python","React"], "fullText": "简历正文…",
"score": { "verdict": "行|待定|不行", "score": 91, "...": "AI打分可后填" }
} ] }
score 可省略(让 AI 现场打);Demo 预置了 score 让首屏即见三色档。
想给新岗位灌测试候选人:照
demo/candidates.demo.json写一份虚构数据,写进data/<slot>/candidates.json即可(注意data/不进 git)。
5 · 扩展点(往哪加功能)
- 新 API:
server.js里是if (p === '/api/xxx')的扁平路由表,照葫芦画瓢加一条;JSON 进出走send()/readBody()。 - 新前端面板:
web/app.js(无框架,直接 DOM);样式web/style.css;SSE 实时日志已接好。 - 新 AI 判定维度:改对应 slot 的
评分卡.json(数据驱动,不碰代码);prompt 拼装在server.js strictScorePrompt()/内核_ai初筛/screen.js。 - 新判断知识:往 slot 的
_rag/*.md加 chunk,RAG 自动检索注入。 - 新简历入口:
resume_parse.js(PDF/docx)/mail_intake.js(IMAP);新格式在resume_field_parse.js加解析。 - 新漏斗阶段逻辑:
stage_model.js(守住「只追踪不自动推进、不自动对外」)。 - 自测:每个模块都有
test_*.js,node test_xxx.js直接跑,加功能顺手加一条。
6 · 安全须知(agent 必须守住的红线)
- OUTREACH 解锁只属于用户本人,agent 绝不代开:对外发送默认关闭(
settings.outreachEnabled:false),唯一合法开启路径是用户本人在设置页阅读风险说明后确认(POST /api/outreach/unlock {confirm:true})。agent 不得调用该端点、不得改 settings.json 置 true、不得绕过限流/留痕对外发任何消息——开不开是产品用户的人工决定,不是 agent 能做的。开启后真发受频率限流(超限拒发)+ 全程留痕(data/outreach_log.jsonl)约束。 - 数据本地、PII 不入仓:候选人真实数据全在
data/(.gitignore焊死),登录态在.chrome-profile/、密钥在config/*_secret.json——全部不进 git。提交前确认没把这些带出去。公开演示只用demo/里的虚构数据。 - 真采集守 ToS、自担风险:
引擎_BOSS推荐牛人自动收藏/是连本机 CDP 端口 9333 调试 Chrome 的真实抓取引擎,需你自己的 BOSS 账号登录、有账号风险,受目标平台 ToS 约束。公开 Demo 不依赖它。真跑前先node 引擎_BOSS推荐牛人自动收藏/_probe_boss_login.js探活登录态;首次小批量、人盯风控。 - 判定口径改数据不改代码:收谁/跳谁是 slot JSON 的 SSOT;别把口径硬编码进
*.js。 - AI 是辅助不是裁决:AI 输出「建议+理由+该问什么」,录谁由人拍板;低置信要明说「建议电话核实 X」,不假装确定。
- 合规提醒:年龄/学历类硬门槛对外使用前需做就业合规审查(评分卡里已把年龄降级为红旗+电话核、不一刀切判杀;学历硬卡建议改「名校加分」而非一票否决)。
7 · 给接手 agent 的一句话
起服务走 §1,看懂架构走 §2,AI 接法走 §3,加岗位走 §4,守红线走 §6。OUTREACH 开关只属于用户、agent 别碰,PII 别入仓、真采集守 ToS、口径改数据不改代码。 公开演示从 npm run seed-demo && npm start 开始,默认不发真消息。