1
0

chain.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. """工具链管理器 - HelloAgents工具链式调用支持"""
  2. from typing import List, Dict, Any, Optional
  3. from .registry import ToolRegistry
  4. class ToolChain:
  5. """工具链 - 支持多个工具的顺序执行"""
  6. def __init__(self, name: str, description: str):
  7. self.name = name
  8. self.description = description
  9. self.steps: List[Dict[str, Any]] = []
  10. def add_step(self, tool_name: str, input_template: str, output_key: str = None):
  11. """
  12. 添加工具执行步骤
  13. Args:
  14. tool_name: 工具名称
  15. input_template: 输入模板,支持变量替换,如 "{input}" 或 "{search_result}"
  16. output_key: 输出结果的键名,用于后续步骤引用
  17. """
  18. step = {
  19. "tool_name": tool_name,
  20. "input_template": input_template,
  21. "output_key": output_key or f"step_{len(self.steps)}_result"
  22. }
  23. self.steps.append(step)
  24. print(f"✅ 工具链 '{self.name}' 添加步骤: {tool_name}")
  25. def execute(self, registry: ToolRegistry, input_data: str, context: Dict[str, Any] = None) -> str:
  26. """
  27. 执行工具链
  28. Args:
  29. registry: 工具注册表
  30. input_data: 初始输入数据
  31. context: 执行上下文,用于变量替换
  32. Returns:
  33. 最终执行结果
  34. """
  35. if not self.steps:
  36. return "❌ 工具链为空,无法执行"
  37. print(f"🚀 开始执行工具链: {self.name}")
  38. # 初始化上下文
  39. if context is None:
  40. context = {}
  41. context["input"] = input_data
  42. final_result = input_data
  43. for i, step in enumerate(self.steps):
  44. tool_name = step["tool_name"]
  45. input_template = step["input_template"]
  46. output_key = step["output_key"]
  47. print(f"📝 执行步骤 {i+1}/{len(self.steps)}: {tool_name}")
  48. # 替换模板中的变量
  49. try:
  50. actual_input = input_template.format(**context)
  51. except KeyError as e:
  52. return f"❌ 模板变量替换失败: {e}"
  53. # 执行工具
  54. try:
  55. result = registry.execute_tool(tool_name, actual_input)
  56. context[output_key] = result
  57. final_result = result
  58. print(f"✅ 步骤 {i+1} 完成")
  59. except Exception as e:
  60. return f"❌ 工具 '{tool_name}' 执行失败: {e}"
  61. print(f"🎉 工具链 '{self.name}' 执行完成")
  62. return final_result
  63. class ToolChainManager:
  64. """工具链管理器"""
  65. def __init__(self, registry: ToolRegistry):
  66. self.registry = registry
  67. self.chains: Dict[str, ToolChain] = {}
  68. def register_chain(self, chain: ToolChain):
  69. """注册工具链"""
  70. self.chains[chain.name] = chain
  71. print(f"✅ 工具链 '{chain.name}' 已注册")
  72. def execute_chain(self, chain_name: str, input_data: str, context: Dict[str, Any] = None) -> str:
  73. """执行指定的工具链"""
  74. if chain_name not in self.chains:
  75. return f"❌ 工具链 '{chain_name}' 不存在"
  76. chain = self.chains[chain_name]
  77. return chain.execute(self.registry, input_data, context)
  78. def list_chains(self) -> List[str]:
  79. """列出所有已注册的工具链"""
  80. return list(self.chains.keys())
  81. def get_chain_info(self, chain_name: str) -> Optional[Dict[str, Any]]:
  82. """获取工具链信息"""
  83. if chain_name not in self.chains:
  84. return None
  85. chain = self.chains[chain_name]
  86. return {
  87. "name": chain.name,
  88. "description": chain.description,
  89. "steps": len(chain.steps),
  90. "step_details": [
  91. {
  92. "tool_name": step["tool_name"],
  93. "input_template": step["input_template"],
  94. "output_key": step["output_key"]
  95. }
  96. for step in chain.steps
  97. ]
  98. }
  99. # 便捷函数
  100. def create_research_chain() -> ToolChain:
  101. """创建一个研究工具链:搜索 -> 计算 -> 总结"""
  102. chain = ToolChain(
  103. name="research_and_calculate",
  104. description="搜索信息并进行相关计算"
  105. )
  106. # 步骤1:搜索信息
  107. chain.add_step(
  108. tool_name="search",
  109. input_template="{input}",
  110. output_key="search_result"
  111. )
  112. # 步骤2:基于搜索结果进行计算
  113. chain.add_step(
  114. tool_name="my_calculator",
  115. input_template="2 + 2", # 简单的计算示例
  116. output_key="calc_result"
  117. )
  118. return chain
  119. def create_simple_chain() -> ToolChain:
  120. """创建一个简单的工具链示例"""
  121. chain = ToolChain(
  122. name="simple_demo",
  123. description="简单的工具链演示"
  124. )
  125. # 只包含一个计算步骤
  126. chain.add_step(
  127. tool_name="my_calculator",
  128. input_template="{input}",
  129. output_key="result"
  130. )
  131. return chain