demo_stuctured.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """
  2. 三级嵌套结构化输出示例
  3. 证明:只需传最外层 Schema,嵌套结构自动展开提取
  4. 嵌套层级:
  5. Company(第一层)
  6. └── Department(第二层)
  7. └── Employee(第三层)
  8. """
  9. from pydantic import BaseModel, Field
  10. import os
  11. from langchain.chat_models import init_chat_model
  12. from langchain_core.messages import SystemMessage, HumanMessage
  13. llm = init_chat_model(
  14. model="deepseek-chat",
  15. model_provider="openai",
  16. api_key=os.environ["DEEPSEEK_API_KEY"],
  17. base_url="https://api.deepseek.com/v1",
  18. temperature=0,
  19. )
  20. from typing import Optional
  21. # ============================================================
  22. # 第三层:员工
  23. # ============================================================
  24. class Employee(BaseModel):
  25. """第三层:单个员工"""
  26. name: str = Field(description="员工姓名")
  27. title: str = Field(description="职位名称")
  28. years: int = Field(description="工作年限")
  29. email: Optional[str] = Field(default=None, description="邮箱,没有则为null")
  30. # ============================================================
  31. # 第二层:部门(包含多个 Employee)
  32. # ============================================================
  33. class Department(BaseModel):
  34. """第二层:部门,内含员工列表"""
  35. dept_name: str = Field(description="部门名称")
  36. budget: float = Field(description="部门年度预算,单位万元")
  37. employees: list[Employee] = Field(default_factory=list, description="部门员工列表")
  38. # ============================================================
  39. # 第一层:公司(包含多个 Department)
  40. # ============================================================
  41. class Company(BaseModel):
  42. """第一层:公司,内含部门列表"""
  43. company_name: str = Field(description="公司名称")
  44. industry: str = Field(description="所属行业")
  45. founded_year: int = Field(description="成立年份")
  46. departments: list[Department] = Field(default_factory=list, description="部门列表")
  47. # ============================================================
  48. # 初始化 DeepSeek 模型(兼容 OpenAI 接口)
  49. # ============================================================
  50. # ============================================================
  51. # 关键:只传最外层 Company,嵌套全部自动展开
  52. # ============================================================
  53. structured_llm = llm.with_structured_output(Company,method="function_calling") # ← 只传这一个!
  54. # ============================================================
  55. # 模拟一段"非结构化的公司介绍文本"
  56. # ============================================================
  57. text = """
  58. 未来科技有限公司成立于2015年,专注于人工智能行业。
  59. 公司目前有两个部门:
  60. 【研发部门】
  61. 年度预算 500 万元,共有两名员工:
  62. - 张伟,职位是算法工程师,工作了 5 年,邮箱 zhangwei@future.com
  63. - 李娜,职位是产品经理,工作了 3 年,暂无邮箱
  64. 【市场部门】
  65. 年度预算 200 万元,共有一名员工:
  66. - 王磊,职位是市场总监,工作了 8 年,邮箱 wanglei@future.com
  67. """
  68. # ============================================================
  69. # 调用:直接传文本,模型自动按三层结构提取
  70. # ============================================================
  71. result: Company = structured_llm.invoke([HumanMessage(content=text)])
  72. print(f'result: {result}')
  73. print("=" * 50)
  74. print(f'result: {result.model_dump()}')
  75. # ============================================================
  76. # 打印结果,验证三层嵌套都被正确提取
  77. # ============================================================
  78. print("=" * 50)
  79. # print(f"公司名称:{result.company_name}")
  80. # print(f"所属行业:{result.industry}")
  81. # print(f"成立年份:{result.founded_year}")
  82. # print(f"部门数量:{len(result.departments)}")
  83. #
  84. # for dept in result.departments:
  85. # print(f"\n 【{dept.dept_name}】预算:{dept.budget} 万元")
  86. # for emp in dept.employees:
  87. # print(f" - {emp.name} | {emp.title} | {emp.years}年 | 邮箱:{emp.email}")
  88. #
  89. # print("=" * 50)
  90. # print("\n✅ 结论:只传了最外层 Company,三层嵌套全部自动提取成功!")