langchain的工具调用
·
Tools 就是给大模型安装的"手和脚",让大模型能够调用外部函数/API来获取实时信息或执行具体操作。
Tools 的工作流程
完整流程
用户问题 → 大模型思考 → 调用Tool → 执行Tool → 结果返回 → 大模型重新组织 → 最终回答
# 1. 用户提问
user_question = "北京今天多少度?顺便计算一下(25+18)/2等于多少?"
# 2. 第一次思考:大模型分析需要调用什么工具
"""
大模型思考:
- 需要天气信息 → 调用 weather_tool
- 需要数学计算 → 调用 calculator_tool
"""
# 3. 大模型返回调用指令(不是最终回答!)
model_response_1 = {
"actions": [
{"tool": "weather_tool", "input": {"city": "北京"}},
{"tool": "calculator_tool", "input": {"expression": "(25+18)/2"}}
]
}
# 4. 你的代码执行这些Tools
weather_result = "北京今天晴,气温25°C" # 真实API调用结果
calc_result = "21.5" # 真实计算结果
# 5. 关键步骤:把结果喂回给大模型,让它重新组织
final_prompt = f"""
用户问题:{user_question}
你已经获取了以下信息:
1. 天气查询结果:{weather_result}
2. 计算结果:{calc_result}
请根据以上信息,组织一个完整的回答给用户。
"""
# 6. 大模型生成最终回答
final_answer = "根据查询,北京今天天气晴朗,温度25°C。另外,(25+18)/2的计算结果是21.5。"
使用 langchain 的 agent 可以自动实现第五步
初期不使用 agent 直接使用大模型调用,只会在响应中返回要调用的大模型
如果使用 agent 则会直接返回调用结果给 agent,让 agent 重新组织回答
用户: "北京天气?计算(25+18)/2"
↓
Agent思考: "需要weather_tool和calculator_tool"
↓
执行: weather_tool("北京") → "25°C"
执行: calculator_tool("(25+18)/2") → "21.5"
↓
Agent自动重新思考: "我有结果了,组织回答"
↓
最终回答: "北京25°C,(25+18)/2=21.5"
创建 tools 的三种方式
方式 1: 不使用注解,纯手动创建
# 第一种类型:手动定义tools
# 定义工具函数
def calculate_expression(expression: str) -> str:
"""计算数学表达式"""
try:
result = eval(expression) # 注意:实际生产环境要用更安全的方法
return f"结果: {result}"
except Exception as e:
return f"计算错误: {e}"
# 包装成Tool
calculator_tool = Tool(
name="calculator", # 工具名称
func=calculate_expression, # 工具函数
description="用于计算数学表达式,例如: '2+3*4' 或 '(5+3)/2'" # 工具描述
)
方式 2:使用装饰器的注解@tools方式
# 第二种类型:使用装饰器注解(方法的注释就是工具描述)
@tool
def weather_check(city: str) -> str:
"""查询城市天气"""
weather_data = {
"北京": "晴,18°C",
"上海": "多云,22°C",
"广州": "小雨,25°C",
"深圳": "阴,26°C"
}
if city in weather_data:
return f"{city}天气: {weather_data[city]}"
else:
return f"未找到{city}的天气信息"
方式 3:使用StructuredTool
class TranslationInput(BaseModel):
text: str = Field(description="要翻译的文本")
target_language: str = Field(description="目标语言")
def translate_text(text: str, target_language: str) -> str:
"""翻译文本到目标语言"""
translations = {
"英语": {"你好": "Hello", "谢谢": "Thank you"},
"日语": {"你好": "こんにちは", "谢谢": "ありがとう"}
}
if target_language in translations:
if text in translations[target_language]:
return f"翻译结果: {translations[target_language][text]}"
else:
return f"未找到'{text}'的翻译"
return f"不支持{target_language}翻译"
translate_tool = StructuredTool.from_function(
func=translate_text,
name="translate_text",
description="翻译文本到目标语言",
args_schema=TranslationInput,
)
示例代码
注意,直接使用大模型不使用 agent 调用,大模型只返回要调用的方法,不会获取结果后重新返回
def demo_agent_usage():
"""演示如何将工具集成到Agent中"""
print("=" * 60)
print("工具调用演示")
print("=" * 60)
# 创建工具列表
tools = [calculator_tool, weather_check, translate_tool]
# 绑定工具列表
llm_with_tools = llm.bind_tools(tools)
# 测试问题(可以修改这里测试不同场景)
test_questions = [
"这个表达式的结果是多少? 2+3*4=",
"北京天气怎么样?",
"把'你好'翻译成日语",
"先计算(10+5)/3,然后告诉我上海天气"
]
for question in test_questions:
print(f"\n📝 用户问题: {question}")
print("-" * 40)
# 调用大模型
response = llm_with_tools.invoke([HumanMessage(content=question)])
# 1. 先打印模型返回的原始消息
print(f"💬 模型回答: {response.content}")
# 2. 检查是否有工具调用
if hasattr(response, 'tool_calls') and response.tool_calls:
print(f"\n🔧 检测到工具调用 ({len(response.tool_calls)}个):")
for i, tool_call in enumerate(response.tool_calls, 1):
# 打印工具调用信息
print(f"\n [{i}] 工具调用详情:")
print(f" 工具名称: {tool_call['name']}")
print(f" 工具参数: {json.dumps(tool_call['args'], ensure_ascii=False, indent=8)}")
# 找到对应的工具对象
tool_obj = None
for tool in tools:
if tool.name == tool_call['name']:
tool_obj = tool
break
if tool_obj:
try:
# 执行工具
print(f" 🚀 执行工具 '{tool_call['name']}'...")
tool_response = tool_obj.invoke(tool_call['args'])
print(f" ✅ 执行结果: {tool_response}")
except Exception as e:
print(f" ❌ 执行失败: {e}")
else:
print(f" ⚠️ 未找到工具: {tool_call['name']}")
else:
print("\n📭 没有工具调用")
更多推荐



所有评论(0)