设置向导之后:调整你收到的内容

先从这里开始:在项目目录运行 docker compose up -d --build,打开 http://127.0.0.1:3000;设置向导(/setup)会问你语言、市场、画像、目标、来源、AI 和 Telegram,并替你写好文件(见 setup.zh.md)。这份指南用在向导之后:按页面讲同样的设置,方便你以后调整。每一步都写了在哪个页面、填什么、怎么确认生效。示意图用的是示例值(柏林 / 德国的设置);你自己的会显示你的市场、城市和货币。

网页地址:本机 http://127.0.0.1:3000,手机 / 其他设备用 Tailscale 地址(data/config/notify.yaml 的 public_base_url)。页面上的改动都会写回项目目录下的 YAML 文件,注释保留;直接改 YAML 也可以,两种方式等价。(项目目录 = 含 package.json、compose.yaml、config/、data/ 的那个目录。)

English version

它怎么工作

默认工作日 07:00、17:00,周末 09:00,按你配置的时区(schedule.yaml)自动跑一轮。每一轮依次经过 6 个环节,你设的每一项条件只作用在其中一个环节。点方块可以跳到对应的设置步骤。

排序值 = AI 匹配分 + 信号加分(有封顶)。被硬过滤掉的岗位不打分、不推送,但仍在库里,可以随时查看并手动"仍然保留"。

职位需求和筛选条件在哪里设?

分成两类,最容易搞混的是前两张卡片:「搜什么」决定去网站上抓哪些岗位;「要什么」决定抓回来以后哪些留下、怎么打分。

我的画像 → 我要什么 /me

抓回来的岗位,哪些留下、哪些过滤?
  • 目标职位(也用于打分)
  • 地点、工作方式、Remote 范围、资历
  • 年薪底线、合同类型
  • 排除学生岗、排除公司、排除关键词

文件 data/profile/preferences.yaml → 第 3 步

设置 → 搜索 /settings

去网站上用什么关键词、在哪些城市搜?
  • 关键词组(每组 OR 合并成一次查询)
  • 城市(每组按城市各查一次)、远程范围
  • 每轮回看多少小时、每组每城市最多几条

文件 data/config/search.yaml → 第 4 步

我的画像 → 关于我 /me

AI 凭什么判断我合不合适?
  • 语言和等级、技能和年限、工作年限
  • 所在城市、是否需要签证担保、给 AI 的简介

文件 data/profile/me.yaml → 第 2 步

感兴趣清单 + 推送 /interests /settings

什么样的岗位排更前、推到手机?
  • 薪酬 / 福利信号词和加分权重、关注公司
  • 推送门槛(默认 70,带薪资或股权信号 60)、静默时段
  • 保存的筛选视图(今日页顶部切换)

→ 第 6 步、第 7 步

⚠️ 两边要对得上。只在 /me 加了一个目标职位、没在 /settings 搜索里加对应关键词,系统根本不会去搜它;反过来,只加了搜索关键词、没写进目标职位,抓回来的岗位职位名匹配分会偏低。改一边时顺手改另一边。

1打开网页,确认系统健康

/sourcespnpm run doctor
  1. 浏览器打开 http://127.0.0.1:3000(手机先打开 Tailscale App 连上,再打开 Tailscale 地址)。左侧导航:今日、岗位、收藏、申请、来源、统计、设置、我的画像、感兴趣清单。
  2. 在项目目录下跑一次体检,看最后一行汇总:
cd <你的项目目录>
pnpm run doctor
全是 ✅ 一切正常,继续下一步。
有 ⚠️ 能用,但有要留意的(例如某通道缺 key)。每项下面有"怎么办"。
有 ❌ 有东西坏了,先按"怎么办"处理再往下。

注意要写 pnpm run doctor,不要只写 pnpm doctor(后者是 pnpm 自带的命令)。doctor 只读,不发消息、不调用 AI、不花钱。网页上的 来源 页能看到同样的信息:每个通道的状态、用量、最近运行,以及 runner 和 ai-worker 的心跳。

2写「关于我」——AI 打分的依据

/me → 关于我data/profile/me.yaml

这部分会以摘要形式发给 AI 打分。至少要填技能或简介,否则打分会暂停(今日页顶部会出现提示横幅)。

127.0.0.1:3000/me
关于我
语言、技能和简介会以摘要形式发给 AI 打分,不要写姓名、联系方式或证件号。
1语言
zh · 母语en · C1de · A2+ 添加语言
语言代码(en、de、zh)+ CEFR 等级。德语等级会和 JD 的德语要求比对。
2技能
Python · 6 年TypeScript · 4 年LLM / RAG · 2 年+ 添加技能
名称 + 年限,写和目标岗位相关的。
3工作年限 / 所在城市
8Berlin
4需要签证担保
需要雇主提供签证担保
5给 AI 的简介几句话:做过什么、擅长什么、下一份工作想做什么方向。AI 打分时最重要的一段文字。不要写姓名、邮箱、电话。
保存还原已保存
改了画像以后:旧分数会被标成"已过期",后续处理轮自动重打;也可以在 /settings 点"重打过期分数"立刻处理。每次保存都会留一份历史快照,/me 页底部可以回滚。

3写「我要什么」——职位需求和筛选条件

/me → 我要什么data/profile/preferences.yaml

这里的条件决定硬过滤(不符合的直接过滤,不打分不推送),目标职位还占预打分的 40%。

127.0.0.1:3000/me
我要什么
目标职位、地点、薪资底线和排除项,用于硬过滤和打分。
1目标职位
AI EngineerLLM EngineerForward Deployed EngineerAI Solutions Engineer输入后按 Enter 添加
和岗位标题比对:整串出现 = 1,词都在但不相邻 = 0.8,命中一半以上 = 0.5。
2地点
BerlinMünchen+
不在这些城市的到岗 / 混合岗位会被过滤。
3工作方式
现场混合远程
4Remote 范围
不接受欧盟内,可在德国雇佣欧盟内任意全球
5资历
不限入门中级资深负责人
6年薪底线(EUR,税前)70000写明的薪资上限低于它才过滤;没写薪资的岗位保留。
7合同类型
长期 接受定期 接受自由职业 接受中介派遣 排除
8排除
排除学生岗(在校生兼职、实习、毕业论文等)
公司:输入后按 Enter关键词:Sales+
保存还原

每一项怎么起作用

#条件不符合时建议
1目标职位不过滤,只影响分数把同义的叫法都列上(AI Engineer / Applied AI Engineer…)
2–4地点、工作方式、Remote 范围过滤,原因如"地点不在目标范围内"只想看远程就去掉"现场""混合";完全不看远程选"不接受"
5资历过滤,原因"级别不符"不确定就留"不限",交给 AI 判断
6年薪底线只有写明上限且低于底线才过滤德国大多数 JD 不写薪资,所以不会误杀
7合同类型"排除"的直接过滤;不在"接受"里的也过滤;JD 没写明合同类型的保留对中介派遣(Temp agency)选"排除"
8学生岗、公司、关键词黑名单过滤关键词按整词匹配职位名和正文,慎用太宽的词
新抓的岗位立刻按新条件过滤。想让库里已有的岗位也按新条件重新过滤:在项目目录下运行 pnpm refilter --dry-run 先看前后对比,确认后去掉 --dry-run 再跑一次(不抓取、不调用 AI)。

4设定搜索条件——去哪里、搜什么

/settings → 搜索data/config/search.yaml
127.0.0.1:3000/settings
处理时间搜索通道AI推送
关键词组
每个关键词组用 OR 合并成一次查询,再按城市各查一次。
1engineering
AI EngineerLLM EngineerMachine Learning Engineer…+
fde_solutions
Forward Deployed EngineerAI Solutions Engineer…+
german
KI EngineerKI-Entwickler+
组 ID 用小写字母、数字和下划线。可以加新组。
地点与远程
2城市
BerlinMünchen+
每个关键词组按城市各查一次。
远程范围
无欧盟内可在德国雇佣欧盟任意全球
时间窗与上限
3回看时间窗(小时)
早轮 24 晚轮 10 周末 24
每组每城市最多条数40
保存runner 已加载(04:12)

查询次数怎么算

每个通道每轮的查询数 ≈ 关键词组数 × 城市数(远程再加一次)。3 组 × 2 城 = 6 次。组越多越全,但付费通道花得越多、免费网站越容易限流。

保存后什么时候生效

保存时用和 runner 相同的规则校验;runner 几秒内热加载,按钮旁显示"runner 已加载"。下一轮采集用新条件,不需要重启。

顺便看一眼「处理时间」标签:默认工作日 07:00 / 17:00、周末 09:00,按你在向导里选的时区(出厂默认是 America/New_York),宿主机关机错过的轮次开机后会补跑。

5确认采集通道——从哪些网站抓

/settings → 通道/sourcesdata/config/sources.yaml.env

通道就是数据来源。在 /settings → 通道 开关和设预算;在 /sources 看每个通道的状态并测试。

127.0.0.1:3000/sources
arbeitsagentur 劳工局正常免费 · 本月 40 条 · 测试 立即采集
linkedin-brightdata正常付费 · $0.00 / $5.00 · 免费额度 225 / 5000
greenhouse · lever · ashby …正常公司招聘页(ATS),名单在 sources.yaml 的 ats_boards
tavily缺 key发现新公司的招聘页 · 需要 TAVILY_API_KEY
类型通道要准备什么
官方 API 和公开的公司数据源,默认开Greenhouse、Lever、Ashby、Personio、SmartRecruiters;劳工局(仅德国市场)不用做什么;把你关心的公司加到 ats_boards
抓取类,默认关Indeed、StepStone(德国包)、LinkedIn guest、XING它们的服务条款可能禁止自动访问。读过抓取一节再打开;向导和 /sources/registry 会要你确认
付费(有月预算)LinkedIn Bright Data、Apify、JSearch把 key 写进项目目录下的 .env,在 /settings 设月预算;不想用就关掉
发现新公司Tavily(默认)/ BraveTAVILY_API_KEY,每月免费 1000 次
需要登录LinkedIn 登录态(默认关,使用你自己的账号)、Gmail 提醒邮件见 LinkedIn 登录态、Gmail 提醒 手册,可选
怎么确认通道能用:/sources 通道卡片上点 测试:只跑第一个查询、最多取 5 条,在内存里解析,不写库、不计预算,结果直接显示在按钮下面。付费和登录态通道没有测试按钮,用"立即采集"。
key 自己填:用文本编辑器打开项目目录下的 .env 填上,保存后运行 docker compose up -d runner 让 runner 读到新值。.env 不进 git,不要把 key 发到聊天里。

6设好推送——什么样的岗位推到手机

/settings → 推送data/config/notify.yaml
/settings · 推送
推送门槛70排序值达到它才推。
带 T1 / T2 信号60写明薪资或有股权的岗位门槛更低。
每轮最多10其余在网页看。
静默时段
22:00–07:00
告警不受静默限制。

推到 Telegram 的每条岗位长这样,按钮直接写进申请记录:

87 · AI Solutions Engineer
Example GmbH · Berlin · 混合
T1 €85–100k英语岗
匹配:LLM 应用经验、客户交付…
👍 感兴趣🚫 忽略📄 定制简历
⭐ 收藏

每轮结束还有一条汇总:新岗位数、通过过滤数、合格数、失败的来源。收到汇总 = 那一轮跑完了。

第一次用 Telegram(默认是关的):按 Telegram 手册用 @BotFather 建 bot,把 TELEGRAM_BOT_TOKEN 和 TELEGRAM_CHAT_ID 填进 .env;然后在 /settings → 手动操作 点 发送 Telegram 测试消息,手机收到即配置成功。

7调排序:信号加分、关注公司、视图

/interestsdata/config/interests.yaml

💶 信号词表和权重

JD 里出现这些说法就加分:T1 写明金额、T2 股权 / 期权、T3 薪资描述、T4 其他。可调每档权重和加分封顶,保存后排序值立刻重算,不调用 AI。

👀 关注公司

添加你特别想去的公司。它们一有新岗位就单独推送,不受分数门槛和过滤限制。还没出现在库里的公司也可以先加。

👁️ 保存的视图

在 /jobs 设好筛选(分数、城市、远程、德语要求…)后点"保存当前筛选为视图",今日页顶部就能一键切换;可设一个默认视图。

每周一 08:00 AI 会根据你的操作(标感兴趣 / 忽略)提出调整建议,出现在 /interests 页,你批准才生效。

8手动跑一轮,看结果

/settings → 手动操作//jobs/<id>/pipeline
  1. 在 /settings → 手动操作 点 立即跑一轮(可以只勾几个通道)。按钮下面实时显示进度:"第 N 轮:x / y 个查询已结束,抓取 z 条"。也可以在终端运行 pnpm cycle:run。
  2. 采集完以后 ai-worker 开始打分,一般几分钟内陆续出分。
  3. 打开 今日:新岗位按排序值排列,顶部是各来源条数。
  4. 点标题进 详情:JD 原文 / 中文翻译、AI 匹配理由和差距、薪酬信号、德语要求、“查看原帖”链接(想标记已申请时点“标为已申请”,打开原帖不会改状态)。
  5. 想投就点"感兴趣",到 申请 看板里拖动状态。
127.0.0.1:3000/
全部默认视图高薪 + Berlin
87
AI Solutions Engineer
Example GmbH · Berlin · 混合 · 2 小时前
T1 薪资英语
👍
74
Applied AI Engineer
Sample AG · München · 远程(EU)
T2 期权
👍
58
ML Engineer (m/w/d)
Demo SE · Berlin · 现场 · 德语 B2
👍
感兴趣
AI Solutions Eng.
Applied AI Eng.
准备中
FDE · Example
已申请
LLM Eng.
面试中
Offer / 已结束

结果不对时怎么查

现象先看哪里
某个想要的岗位没出现/jobs 打开"显示已过滤",搜它:详情页顶部写着过滤原因(例如"地点不在目标范围内")。可以点"仍然保留",或回到第 3 步放宽条件
压根没抓到这类岗位第 4 步的关键词组里有没有这个叫法;第 5 步通道是否正常
分数一直是空的/me 有没有填技能或简介;pnpm run doctor 的「AI 没有积压」「ai-worker 心跳新鲜」两项
分数都偏低第 2 步的简介和技能写得够不够具体;第 3 步目标职位是否覆盖常见叫法
手机没收到推送是否在静默时段;排序值是否够门槛;/settings 发一条 Telegram 测试消息

✓之后每天

  • 什么都不用启动:按部署指南配置好主机之后,Docker 和 ai-worker 会开机自动运行,每天 3 轮自动跑。
  • 看 Telegram:合格的新岗位逐条推来,👍 / 🚫 直接处理;想先存着的点 ⭐ 收藏。
  • 有空打开 今日 或 岗位 浏览没推送的;申请 看板跟进进度,超时没回复会提醒。
  • 周一看看 /interests 里的 AI 调整建议,批准或拒绝。
  • 觉得不对劲时跑 pnpm run doctor;出问题 Telegram 也会主动告警(通道熔断、预算到 80%、ai-worker 掉线等)。

更多:日常使用 usage · 设置页细节 settings · 部署和体检项 deploy · 配置说明 configuration