Clipdf 是一个本地简历解析 CLI / Agent。它可以读取 PDF 简历,调用大模型提取结构化信息,也可以结合 JD 做匹配评分。
项目提供两种入口:
- 快捷命令:直接执行
parse、extract、score - 对话模式:执行
chat,用自然语言让 Agent 选择合适的 skill
- 解析 PDF 简历文本
- 将简历提取为结构化 JSON
- 根据 JD 对候选人做匹配评分
- 支持
--output保存 JSON 结果 - 支持
--mock,无 API Key 也能演示 - 支持 OpenAI-compatible 国产大模型接口
- 使用 Markdown 声明 skills,再由 Agent 根据意图选择执行
chat模式支持会话记忆和最终回复流式输出- 使用 Pydantic 校验 AI 返回的结构化 JSON
python3 -m venv .venv
.venv/bin/python -m pip install -e .查看命令:
.venv/bin/resume-cli --help真实 AI 模式读取项目根目录的 config.json。
复制示例配置:
cp config.example.json config.json填写你的模型服务商配置:
{
"ai": {
"api_key": "你的 API Key",
"base_url": "你的 OpenAI-compatible Base URL",
"model": "你的模型名"
}
}例如通义 / 百炼 OpenAI-compatible 模式:
{
"ai": {
"api_key": "sk-xxxx",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "qwen-plus"
}
}config.json 已加入 .gitignore,不要提交真实 Key。只想演示时可以不配置,命令里加 --mock。
解析 PDF 文本:
.venv/bin/resume-cli parse examples/sample_resume.pdf提取结构化简历 JSON:
.venv/bin/resume-cli extract examples/sample_resume.pdf --mock根据 JD 评分:
.venv/bin/resume-cli score examples/sample_resume.pdf --jd examples/jd.txt --mock进入对话模式:
.venv/bin/resume-cli chat --mock真实 AI 模式去掉 --mock:
.venv/bin/resume-cli extract examples/sample_resume.pdf
.venv/bin/resume-cli score examples/sample_resume.pdf --jd examples/jd.txt
.venv/bin/resume-cli chat这组命令验证基础 CLI、PDF 解析和错误提示。
.venv/bin/resume-cli --help
.venv/bin/resume-cli parse examples/sample_resume.pdf
.venv/bin/resume-cli parse not-exist.pdf
.venv/bin/resume-cli parse examples/broken.pdf预期:
--help能看到parse / extract / score / chat- 合法 PDF 输出纯文本
- 不存在文件、损坏 PDF 输出清晰错误
这组命令不需要 API Key,验证 extract、score、--output 和 Markdown skills。
.venv/bin/resume-cli extract examples/sample_resume.pdf --mock
.venv/bin/resume-cli score examples/sample_resume.pdf --jd examples/jd.txt --mock
.venv/bin/resume-cli extract examples/sample_resume.pdf --mock --output result.json
.venv/bin/resume-cli score examples/sample_resume.pdf --jd examples/jd.txt --mock --output score.json预期:
extract输出简历 JSONscore输出评分 JSON- AI 返回 JSON 会经过 Pydantic 字段校验
result.json和score.json被写入本地
这组命令验证对话模式、会话记忆和最终回复流式输出。
启动 mock 对话:
.venv/bin/resume-cli chat --mock单轮示例:
帮我解析 examples/sample_resume.pdf 并保存到 result.json
多轮记忆示例:
简历在 examples/sample_resume.pdf
examples/jd.txt 这里有个 jd,对这个简历做评分
缺参数追问示例:
解析下简历
预期:
- 单轮请求能选择
extract_resume_from_pdf - 多轮请求能记住上一轮的 PDF 路径
- 缺少 PDF 路径时会追问,不会编造
resume.pdf - 规划、读取文件、调用 AI、写文件等非流式阶段会显示
[状态]提示
也可以用管道快速验证:
printf '简历在 examples/sample_resume.pdf\nexamples/jd.txt 这里有个 jd,对这个简历做评分\nexit\n' | .venv/bin/resume-cli chat --mocksrc/resume_cli/
cli.py # CLI 入口:parse / extract / score / chat
config.py # 读取 config.json
errors.py # 用户可读异常
json_utils.py # AI JSON 容错解析
output.py # JSON 输出与写文件
pdf_reader.py # PDF 文本提取
schemas.py # 简历 JSON 和评分 JSON 数据结构
tools/
registry.py # ToolRegistry,统一注册 tool 和 skill
pdf_tools.py # parse_pdf
jd_tools.py # read_jd
ai_tools.py # extract_resume / score_resume
file_tools.py # write_json
skills/
extract_resume_from_pdf.md
score_resume_with_jd.md
registry.py # 读取 Markdown skill 并注册为可执行能力
model/
client.py # OpenAI-compatible AI 客户端
mock.py # mock AI 客户端
agent/
loop.py # 对话循环:规划 -> 执行 -> 回复
memory.py # 会话对象记忆
planner.py # mock 模式的规则规划器
tools/ 是原子能力:
parse_pdf:读取 PDF 文本read_jd:读取 JD 文本extract_resume:调用 AI 提取简历 JSONscore_resume:调用 AI 做匹配评分write_json:写入 JSON 文件
skills/ 是组合能力,用 Markdown 描述:
extract_resume_from_pdf:parse_pdf -> extract_resume -> 可选 write_jsonscore_resume_with_jd:parse_pdf -> read_jd -> score_resume -> 可选 write_json
CLI 快捷命令和 chat Agent 都通过同一个 ToolRegistry 执行能力。
mock 模式使用简单规则:
- 出现“解析 / 提取 / 结构化”并带
.pdf,选择extract_resume_from_pdf - 出现“评分 / 匹配 / JD”并带
.pdf、.txt,选择score_resume_with_jd
真实 AI 模式会把 tool / skill 描述和会话记忆发送给模型,由模型返回 action JSON:
{
"type": "tool",
"tool": "extract_resume_from_pdf",
"arguments": {
"pdf_path": "examples/sample_resume.pdf",
"output": "result.json"
}
}会话记忆只记录后续可能被引用的对象:
- 用户明确提到的文件路径,例如 PDF、JD、输出 JSON
- skill 执行后的最终结果,例如简历解析结果、评分结果
它不会记录 PDF 全文、分数字段、文件扩展名、工具中间步骤等可以重新推导出来的信息。
examples/sample_resume.pdf:示例简历 PDFexamples/jd.txt:示例 JDexamples/broken.pdf:损坏 PDF,用于验证异常处理
- PDF 文本提取依赖
pypdf,扫描件或纯图片 PDF 可能提取为空 - mock 模式的意图识别是关键词规则,不代表真实模型效果
- 真实模型需支持 OpenAI-compatible Chat Completions 接口
- 部分国产模型可能不完全支持
response_format={"type": "json_object"},代码已做基础 JSON 清洗,但仍建议选择 JSON 输出稳定的模型