needq_agent.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # -*- coding: utf-8 -*-
  2. """
  3. 需风量计算 Agent 创建与配置模块
  4. 核心功能:
  5. - 创建需风量计算 DeepAgent(整合 Skills + 计算工具 + MCP 数据)
  6. - 配置流式输出
  7. - 管理 Agent 实例生命周期
  8. 架构:
  9. - 模型: 通过 vent_agent._get_model() 获取
  10. - Skills: needq-calc(需风量计算技能)
  11. - Tools: 14个 calc_tools 计算函数 + write_todos + get_needq_all_data
  12. - Backend: FilesystemBackend(virtual_mode)
  13. - 系统提示词仅包含通用行为准则,具体计算规则在各技能的 SKILL.md 中
  14. """
  15. import os
  16. from pathlib import Path
  17. from typing import Optional
  18. from dotenv import load_dotenv
  19. load_dotenv()
  20. SKILLS_ROOT = str((Path(__file__).parent.parent / "skills").resolve())
  21. # 复用现有项目的模型加载
  22. from agents.vent_agent import _get_model
  23. # 导入 write_todos
  24. from langchain.agents.middleware.todo import write_todos
  25. # 导入全部计算工具
  26. from tools.calc_tools import (
  27. calc_face_by_gas,
  28. calc_face_by_workers,
  29. calc_face_by_wind_speed,
  30. calc_face_air_volume_max,
  31. calc_tunnel_by_gas,
  32. calc_tunnel_by_explosives,
  33. calc_tunnel_by_workers,
  34. calc_tunnel_by_wind_speed,
  35. calc_tunnel_air_volume_max,
  36. calc_chamber_by_equipment,
  37. calc_chamber_by_wind_speed,
  38. calc_other_by_wind_speed,
  39. calc_effective_area,
  40. calc_total_air_volume,
  41. )
  42. # 导入 MCP 工具
  43. from tools.vent_tools import get_needq_all_data
  44. # ============================================================
  45. # 系统提示词(仅通用行为准则,不写计算规则)
  46. # ============================================================
  47. NEEDQ_CALC_SYSTEM_PROMPT = """你是一名煤矿通风需风量计算专家,帮助用户交互式计算各用风地点的需风量。
  48. ## 全局通用行为准则
  49. 1. **必须调用工具计算**:所有需风量计算必须通过调用 calc_tools 中的工具函数完成,绝对禁止凭 LLM 知识直接给出计算结果。此条为红线。
  50. 2. **参数缺失要追问**:若用户未提供必要计算参数,明确列出所需参数并引导用户补充,绝不编造参数值。
  51. 3. **列式计算**:展示每个计算过程的公式 → 代入数值 → 计算结果,不能只给结果。
  52. 4. **多轮对话承接**:记住当前会话中的用风地点类型和已有参数,用户补充参数或要求调整时自动衔接。
  53. 5. **全程简体中文输出**。
  54. 6. **禁止输出 ANSI 转义序列、内部工具名、函数名、技能标识**。
  55. 7. **全流程使用 write_todos 工具**实时更新任务进度。
  56. 8. 所有数据来源于工具调用结果,绝不编造数据。
  57. 9. 引用规程时附上具体条款来源(《煤矿安全规程》2025版、AQ 1056-2008)。
  58. 10. 无法判断时诚实说明原因,不臆测。
  59. ## 支持的用风地点类型
  60. - 采煤工作面(含备用工作面)
  61. - 掘进工作面
  62. - 机电硐室
  63. - 其他用风地点(主要进回风巷、采区进回风巷、其他通风人行巷道等)
  64. - 多地点汇总
  65. - 通防管控平台数据查询
  66. ## 工作模式
  67. 严格按照技能(skill: needq-calc)中定义的流程执行任务:
  68. 1. 识别用风地点类型
  69. 2. 收集/提取计算参数
  70. 3. 调用计算工具
  71. 4. 格式化输出结果
  72. 5. 支持参数调整重算
  73. """
  74. # ============================================================
  75. # Agent 工厂函数
  76. # ============================================================
  77. def create_needq_calc_agent():
  78. """创建「需风量计算」Agent。
  79. 该 Agent 专门处理各用风地点的需风量交互式计算,具备:
  80. - 14个计算工具(覆盖采煤面/掘进面/硐室/其他巷道)
  81. - MCP 远程数据查询能力(get_needq_all_data)
  82. - 多轮对话参数承接能力
  83. - 结构化计算报告输出能力
  84. Returns:
  85. CompiledStateGraph: 编译后的 LangGraph 状态图,支持 .invoke() 和 .stream()
  86. """
  87. from deepagents import create_deep_agent
  88. from deepagents.backends import FilesystemBackend
  89. from deepagents import FilesystemPermission
  90. _project_root = str(Path(__file__).parent.parent)
  91. skills = ["skills/needq-calc"]
  92. print(f"[skills] Agent=needq-calc-agent skills={skills}")
  93. agent = create_deep_agent(
  94. model=_get_model(),
  95. tools=[
  96. # 基础工具
  97. write_todos,
  98. # 辅助工具
  99. calc_effective_area,
  100. calc_total_air_volume,
  101. # 采煤工作面计算
  102. calc_face_by_gas,
  103. calc_face_by_workers,
  104. calc_face_by_wind_speed,
  105. calc_face_air_volume_max,
  106. # 掘进工作面计算
  107. calc_tunnel_by_gas,
  108. calc_tunnel_by_explosives,
  109. calc_tunnel_by_workers,
  110. calc_tunnel_by_wind_speed,
  111. calc_tunnel_air_volume_max,
  112. # 硐室计算
  113. calc_chamber_by_equipment,
  114. calc_chamber_by_wind_speed,
  115. # 其他巷道计算
  116. calc_other_by_wind_speed,
  117. # MCP 远程数据查询
  118. get_needq_all_data,
  119. ],
  120. skills=skills,
  121. system_prompt=NEEDQ_CALC_SYSTEM_PROMPT,
  122. backend=FilesystemBackend(root_dir=_project_root, virtual_mode=True),
  123. permissions=[
  124. FilesystemPermission(operations=["write"], paths=["/**"], mode="deny"),
  125. ],
  126. middleware=[],
  127. name="needq-calc-agent",
  128. )
  129. return agent
  130. # ============================================================
  131. # 单例缓存
  132. # ============================================================
  133. _needq_calc_agent: Optional[object] = None
  134. def get_needq_calc_agent():
  135. """获取需风量计算 Agent 单例"""
  136. global _needq_calc_agent
  137. if _needq_calc_agent is None:
  138. _needq_calc_agent = create_needq_calc_agent()
  139. return _needq_calc_agent