JobOracle 适合做这些事情:
- 就业行情分析
- 求职指导建议
- 城市机会对比
- OfferStar 岗位汇总页辅助检索
- Markdown 报告输出
- 无外部搜索或 LLM 时自动降级到本地规则模式
当前项目采用标准 src 布局,核心代码位于 src/JobOracle。
JobOracle/
├── assets/ # Logo 等静态资源
├── src/JobOracle/ # 核心实现
├── reports/ # 生成的 Markdown 报告
├── jobs_dataset/ # OfferStar 抓取快照(CSV / JSON)
├── .env.example # 环境变量示例
└── pyproject.toml
推荐使用 uv:
uv sync如果你更习惯 pip:
pip install -e .默认读取项目根目录下的 .env。可以先参考 .env.example。
主要变量:
EMPLOYMENT_API_KEYEMPLOYMENT_BASE_URLEMPLOYMENT_MODEL_NAMEEMPLOYMENT_TIMEOUT_SECONDSEMPLOYMENT_REPORT_DIREMPLOYMENT_SEARCH_API_KEYEMPLOYMENT_SEARCH_PROVIDEREMPLOYMENT_SEARCH_TIMEOUT_SECONDSEMPLOYMENT_MAX_SEARCH_RESULTS
兼容旧变量名:
REPORT_ENGINE_API_KEYREPORT_ENGINE_BASE_URLREPORT_ENGINE_MODEL_NAMEQUERY_ENGINE_API_KEYQUERY_ENGINE_BASE_URLQUERY_ENGINE_MODEL_NAMEOPENAI_API_KEYTAVILY_API_KEY
推荐运行方式:
uv run src/JobOracle/cli.py "2026 年杭州算法岗就业行情如何"如果已经执行过 pip install -e .,也可以:
python -m JobOracle.cli "2026 年杭州算法岗就业行情如何"CLI 默认会输出这些过程信息:
- 分析模式
- 检索查询规划
- 检索结果数量
- OfferStar 抓取进度
Researcher / Analyst / Advisor阶段状态- 最终报告保存位置
求职指导示例:
uv run src/JobOracle/cli.py "我是统计学本科,想去深圳找数据分析工作,应该怎么准备" \
--mode guidance仅输出最终结果:
uv run src/JobOracle/cli.py "2026 年杭州算法岗就业行情如何" --quiet当前项目已经提供一个临时 Chainlit 前端,用于验证多轮对话、记忆累积和“聊天 / 报告”两种模式。
启动方式:
uv run chainlit run src/JobOracle/ui/chainlit_app.py如果你使用项目自带虚拟环境,也可以:
.venv/bin/chainlit run src/JobOracle/ui/chainlit_app.py当前前端能力包括:
- 多轮聊天输入
- 会话自动维护
- 用户画像侧边展示
- 当前任务与待补充信息展示
生成报告导出 Markdown重置会话
说明:
- 这是一层临时前端,目的是验证多轮交互体验。
- 核心逻辑仍然在 Python service 层,后续可以替换成其他 UI 方案。
JobOracle 支持通过 --profile-json 或 --profile-file 传入用户画像,并会自动做字段标准化。
推荐字段:
educationschoolmajorgraduation_yeartarget_citiestarget_rolesskillsinternshipprojectspreferred_industries
说明:
- 列表字段既支持 JSON 数组,也支持逗号分隔字符串。
- 支持一部分中文键名自动映射到标准字段。
- 画像会参与查询规划、提示词构建和最终报告生成。
使用 --profile-json:
uv run src/JobOracle/cli.py "我适合投什么数据岗位" \
--mode guidance \
--profile-json '{"education":"本科","school":"江西财经大学","major":"统计学","target_cities":["深圳","广州"],"target_roles":["数据分析","商业分析"],"skills":["Python","SQL","Tableau"],"internship":"电商运营实习","projects":["用户增长分析项目"],"preferred_industries":["互联网","消费"]}'使用 --profile-file:
uv run src/JobOracle/cli.py "我适合投什么数据岗位" \
--mode guidance \
--profile-file profile.json示例 profile.json:
{
"education": "本科",
"school": "江西财经大学",
"major": "统计学",
"target_cities": ["深圳", "广州"],
"target_roles": ["数据分析", "商业分析"],
"skills": ["Python", "SQL", "Tableau"],
"internship": "电商运营实习",
"projects": ["用户增长分析项目"],
"preferred_industries": ["互联网", "消费"]
}如果希望在分析时顺带使用 OfferStar 公开岗位汇总数据:
uv run src/JobOracle/cli.py "我是武汉大学计算机毕业生,当前准备在武汉找工作,有什么建议吗" \
--mode guidance \
--use-offerstar \
--offerstar-from-page 1 \
--offerstar-to-page 5 \
--offerstar-max-items 60抓取快照会保存到 jobs_dataset/。
当前抓取逻辑:
- 支持页码范围抓取
- 如果范围中包含第
1页,会优先抓取第1页 - 后续页码会随机打乱,避免总是只落在前几页公司
- 单城市问题会带上城市筛选
- 多城市问题不会强行缩成单城市筛选
- 当前分页参数按
current=<页码>&pageSize=20构造
单独抓取 OfferStar:
uv run src/JobOracle/cli.py crawl-offerstar \
--question "深圳 算法岗 华为 人工智能" \
--from-page 1 \
--to-page 5 \
--max-items 100手动指定筛选项:
uv run src/JobOracle/cli.py crawl-offerstar \
--industry "人工智能" \
--work-location "深圳" \
--company "华为" \
--positions "算法" \
--from-page 1 \
--to-page 5 \
--max-items 100系统不是单次 LLM 直接输出,而是一个轻量三角色流程,且不依赖任何 Multi-Agent 框架:
Researcher负责信息检索和证据整理。Analyst负责把证据转成结构化判断。Advisor负责生成最终就业分析和行动建议。
检索层会优先尝试外部搜索和 OfferStar;如果外部能力不可用,则自动回退到本地推断证据。
系统也会尽量把宽泛岗位拆成更接近真实投递场景的细分方向,例如:
数据分析->业务数据分析 / BI数据分析 / 增长分析算法->算法工程师 / AI应用工程师 / 机器学习工程师产品->B端产品经理 / 数据产品经理 / 增长产品经理
如果没有可用的 LLM 配置,或者外部网络暂时不可用,系统会自动退回本地规则模式。此时依然会执行:
- 查询词规划
- 轻量证据生成
- 三角色协作
- Markdown 报告输出
- 小而独立
- 面向命令行优先
- 不依赖复杂任务编排
- 先保证闭环,再逐步增强效果