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📭 没有工具调用")
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐