当前位置: 首页 > news >正文

Agent-study项目教程(02):智能简历结构化提取工具

一、理论部分

1. 为什么要“结构化输出”:从文本到可编排数据

在 Agent 开发中,模型输出如果只是自然语言文本,往往难以被程序可靠消费;而一旦把输出约束为结构化数据(如 JSON),就可以直接用于:

  • 写入数据库/生成文件(JSON、CSV)
  • 作为下一步工具调用的参数(函数调用、工作流编排)
  • 做校验、做评估、做自动化测试

因此,“让模型稳定输出符合规范的数据结构”是从聊天走向可落地系统的关键一步。

2. 用 Pydantic 定义“目标数据结构”:让模型做填空题

实现结构化输出的核心不是“让模型自己随便写 JSON”,而是先明确你需要的数据结构,然后让模型按这个结构填写。

Pydantic 的价值在于:

  • 用 Python 类型定义字段(必填/可选、列表、嵌套对象)
  • 自动生成 JSON Schema(可作为约束条件写入提示词)
  • 对模型输出进行校验(不合格就直接报错,便于定位问题)

在本项目中,我们定义了EducationWorkExperienceResume三个模型,最终希望模型输出一个完整的ResumeJSON。

3. “双重约束”保证稳定:System Prompt + JSON Mode + 低温度

仅靠提示词约束,有时模型仍可能输出多余解释、Markdown 包裹或字段缺失。本项目采用三项组合策略来提高稳定性:

  • System Prompt 明确输出要求:只输出纯 JSON,不要 Markdown,不要解释文本
  • JSON Mode(response_format):让服务端强制返回 JSON 对象格式(尽量减少跑偏)
  • temperature=0.0:信息抽取类任务追求稳定一致,一般将温度设为 0

此外,得到模型输出后还会再用 Pydantic 做一次校验,实现“生成—校验”的闭环。


二、实战部分

1. 项目目标

实现一个“简历结构化提取工具”,输入一份简历文本(例如resume.txt),输出一份结构化 JSON,字段包括:

  • 基本信息:姓名、邮箱、电话
  • 技能:技能列表
  • 教育经历:学校/专业/学位/时间段
  • 工作经历:公司/岗位/工作描述摘要

2. 运行准备

请确保本地已安装依赖,并配置好环境变量(不要把真实密钥写进代码或公开仓库):

依赖安装(示例):

pipinstall-rrequirements.txt

环境变量(示例):

  • DEEPSEEK_API_KEY
  • DEEPSEEK_BASE_URL

输入文件:将待解析简历放在项目目录下的resume.txt(项目已提供示例文件)。

3. 项目代码(完整实现)

下面给出项目的完整代码(核心逻辑完整,篇幅可控,便于直接运行):

importosimportjsonfromopenaiimportOpenAIfromdotenvimportload_dotenvfrompydanticimportBaseModel,FieldfromtypingimportList,Optional# 加载环境变量# 假设 .env 文件在项目根目录project_root=os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))load_dotenv(os.path.join(project_root,".env"))client=OpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"),base_url=os.getenv("DEEPSEEK_BASE_URL"),)# 1. 定义目标数据结构(Pydantic Model)classEducation(BaseModel):school:str=Field(...,description="学校名称")major:str=Field(...,description="专业")degree:str=Field(...,description="学位,如本科、硕士")year:str=Field(...,description="毕业年份或就读时间段")classWorkExperience(BaseModel):company:str=Field(...,description="公司名称")role:str=Field(...,description="职位")description:str=Field(...,description="工作描述摘要")classResume(BaseModel):name:str=Field(...,description="候选人姓名")email:Optional[str]=Field(None,description="电子邮箱")phone:Optional[str]=Field(None,description="联系电话")skills:List[str]=Field(...,description="技能列表")education:List[Education]=Field(...,description="教育背景列表")work_experience:List[WorkExperience]=Field(...,description="工作经历列表")defextract_resume_info(file_path:str):# 2. 读取简历文本try:withopen(file_path,"r",encoding="utf-8")asf:resume_content=f.read()exceptFileNotFoundError:print(f"错误: 找不到文件{file_path}")returnNoneprint(f"正在分析简历:{file_path}...")# 3. 构造 Prompt:输出必须严格遵循 Schemasystem_prompt=f""" 你是一个专业的简历解析助手。请从用户的简历文本中提取关键信息。 请严格按照以下 JSON 格式输出,不要包含任何 Markdown 格式标记(如 ```json ... ```),只输出纯 JSON 字符串。 目标 JSON 结构定义如下:{json.dumps(Resume.model_json_schema(),indent=2,ensure_ascii=False)}""".strip()messages=[{"role":"system","content":system_prompt},{"role":"user","content":resume_content},]# 4. 调用 API:JSON Mode + 低温度保证稳定try:response=client.chat.completions.create(model="deepseek-chat",messages=messages,temperature=0.0,response_format={"type":"json_object"},)result_json=response.choices[0].message.content# 5. 解析并验证:不符合结构就会抛错,便于调试与兜底resume_data=Resume.model_validate_json(result_json)# 6. 输出结构化结果print("\n提取成功。结构化数据如下:\n")print(json.dumps(resume_data.model_dump(),indent=2,ensure_ascii=False))returnresume_dataexceptExceptionase:print(f"\n发生错误:{e}")if"result_json"inlocals():print(f"原始返回内容:{result_json}")returnNoneif__name__=="__main__":current_dir=os.path.dirname(os.path.abspath(__file__))resume_path=os.path.join(current_dir,"resume.txt")extract_resume_info(resume_path)

4. 如何运行

在项目根目录执行:

python stage_01_llm_basics/project_02_resume_extractor/extractor.py

5. 运行结果示例

如果输入的resume.txt类似“张三 / 电话 / 邮箱 / 教育背景 / 工作经历 / 技能清单”这种结构,运行后你将得到类似如下的结构化输出(示例):

{"name":"张三","email":"zhangsan@example.com","phone":"138-0013-8000","skills":["Java","Python","Golang","C++","MySQL","Redis","MongoDB","Git","Docker","Kubernetes","英语","普通话"],"education":[{"school":"清华大学","major":"计算机科学与技术","degree":"本科","year":"2018.09 - 2022.06"}],"work_experience":[{"company":"字节跳动","role":"后端开发工程师","description":"负责推荐系统后端开发,优化接口响应时间;参与高并发方案设计;使用Golang重构部分服务提升吞吐。"},{"company":"腾讯","role":"后台开发实习生","description":"参与微信支付营销活动后台开发;编写自动化测试脚本提升测试效率。"}]}

6. 项目总结

  • 结构化输出是 Agent 工程化的前提:让模型输出变成程序可直接消费的数据。
  • Pydantic 提供了“先定义结构,再生成约束,再做校验”的完整闭环,显著提升稳定性。
  • System Prompt + JSON Mode + temperature=0.0 的组合适用于“信息抽取/格式化”任务,可作为后续工具调用参数生成的通用模板。
http://www.jsqmd.com/news/1391496/

相关文章:

  • CPU占用过高排查实战:从监控到代码优化的系统性解决方案
  • 三天让旧PC变身macOS主机:这份黑苹果安装教程带你看完从体检到验收的全过程
  • Manta高级技巧:自定义回调函数处理Dota 2 replay原始数据
  • 旧款Mac免费升级新系统的终极方案:OpenCore Legacy Patcher实操指南,3步告别淘汰焦虑
  • 炉石传说插件 HsMod 免费开源指南:60 多项实用功能,从安装到进阶一次讲透
  • PyCharm配置Conda解释器:实现Python项目环境隔离与可复现性
  • 老Mac免费吃上最新macOS:OpenCore Legacy Patcher 保姆级实操指南,跟着照做一次跑通
  • 163MusicLyrics免费歌词下载指南:如何为整个音乐库快速批量匹配LRC歌词
  • 免费文档下载工具实操指南:3 个步骤一键下载百度文库等 30+ 平台文档
  • 从AI助手失败案例看LLM应用开发:工程实践与测试指南
  • Pygalmesh表面重网格化教程:狮子头模型优化实例详解
  • 互联网、国企、芯片、通信、车企五大技术领域职业选择全解析
  • Python商品推荐系统毕业设计:从数据爬取到算法集成的工程化实践
  • mootdx 通达信数据接入实战手册:七步吃透行情、财务与离线数据三大能力
  • 免费开源的PDF工具箱PDF补丁丁,一次解决书签、尺寸、加密、改名等难题
  • 五百亿网站建设需要多少钱?揭秘高端企业官网背后的真实成本与核心价值
  • Adafruit_neoPixel 1.14.0新版解析:从PY32到Arduino Giga,让WS2812灯带实现“换板自由“
  • python的工业过程控制场景模拟第一百三十四篇:实现多组控制回路优先级调度,安全联锁回路拥有最高执行优先级。
  • Trolol新手入门:最有趣的5个整蛊命令,让朋友哭笑不得
  • 网站建设公司广告语怎么选才能打动客户?揭秘高转化率文案背后的逻辑与真相
  • 炉石传说HsMod插件实用指南:从安装到进阶的完整梳理
  • 十年前的旧Mac还能装最新macOS?OpenCore Legacy Patcher从零上手指南
  • Linux内核开发模型深度解析:为何它颠覆传统软件开发?
  • 2026 年 8 月辽阳房屋漏水科普:台风暴雨叠加回潮,房屋渗水维修怎么选 - 筑宅安
  • 开源电影级AI视频提示词库:从专业分镜到批量生产实战指南
  • 163MusicLyrics歌词下载工具:免费批量搞定网易云与QQ音乐LRC歌词,新手3分钟就能上手
  • 抖音批量下载工具实测:4小时素材整理,我用它压到25分钟
  • KMS激活工具KMS_VL_ALL_AIO使用教程:3步搞定Windows和Office自动续期激活
  • Windows 11 系统安装与重装完整教程(2026年最新版)
  • 免费字幕编辑神器 SubtitleEdit 入门教程:一个晚上从零做出一集带字幕的视频