💻
QMMMS的笔记
博客
  • QMMMS的笔记
  • agent
    • MCP的背景、原理和开发
    • Agent 历史与背景
    • Agentic Workflows
    • 环境检查与基础工具
    • Tool Call
    • 工具与运行时的值
    • temp
    • 处理 Tool Call error
    • trick
  • algorithm
    • 线性结构
    • 二叉树
    • 图
    • 查找
    • 排序
    • 动态规划
    • 优化方法
    • 数学
    • 迁移至Java
  • computer_composition
    • 系统总线
    • 存储器
    • 输入输出系统
    • 计算机的运算方法
    • 指令系统
    • 补充
  • computer_network
    • 引入
    • 应用层
    • 传输层
    • 网络层(数据平面)
    • 网络层(控制平面)
    • 链路层
    • 常见问答
    • 实验
  • database
    • SQL实战
    • 关系代数
    • 数据库设计
    • 规范化
    • 数据库基本概念
    • 查询原理
    • 数据库恢复技术
    • 并发控制
  • dev_tools
    • Git
    • Nginx
    • Spring
    • LangChain
    • PyTorch Cheat Sheet
    • MyBatis
    • MySQL Cheat Sheet
    • MySQL 补充
    • Redis
    • Docker
    • RocketMQ
    • Chrome
  • linux
    • Linux基础命令与使用
    • 文件与权限
    • 文件与目录操作
    • 权限属性高级
    • 命令与文件的查找
    • 文件压缩和打包
    • vim编辑器
    • shell变量
    • 命令补充
    • 数据流重定向
    • 管道命令
    • shell脚本
    • 用户管理
    • 用户间交流
    • 计划任务
    • 进程管理
    • 软件管理
    • 认识系统服务
    • 运维常用命令
    • 常用命令
  • llm
    • 大规模语言模型概述
    • 分布式训练概述
    • 有监督微调概述
    • 强化学习与LLM
    • LLM评估概述
    • 大模型应用
    • 理解大模型
    • 量化
    • 预训练
    • 上下文学习
  • machine_learning
    • 引入
    • 大致正确学习
    • 一致收敛
    • 偏差还是过拟合?
    • 可学习的充要条件
    • 非均匀可学习性
    • 计算复杂性
  • mathematics
    • 概率与统计基础
    • 线性代数基础
  • operating_system
    • 操作系统基本概念
    • 进程和线程
    • 同步,互斥与死锁
    • 内存管理
    • 文件系统
    • I/O系统
    • 保护与安全
    • 《现代操作系统》
  • statistical_learning
    • 统计学习引入
    • 线性回归
    • 分类
    • 重抽样方法
    • 线性模型选择与正则化
    • 非线性模型
    • 基于树的方法
    • 支持向量机
    • 无指导学习
    • 马尔科夫链和蒙托卡罗方法简明理解
    • R语言速查
  • deep_learning
    • basic_concepts
      • 逻辑回归与损失函数
      • 神经网络
      • 正则化、预处理、权重初始化
      • 优化算法
      • 机器学习策略
      • 复习:从计算机视觉的角度
      • 卷积神经网络
      • 深度卷积网络示例
      • 计算机视觉任务
      • 循环神经网络
      • 自然语言处理任务
      • 注意力
      • Transformers 家族
      • 显卡扫盲
      • 强化学习概述
    • semi-supervise
      • 半监督学习简介
      • Consistency Regularization
      • Proxy-label Methods
      • Holistic Methods
      • Generative Models
      • Graph-Based SSL
      • Self-Supervision for SSL
      • Other SSL methods
  • programming
    • cpp
      • STL
      • C++基础
      • 内存管理
      • 面向对象
    • java
      • 环境和介绍
      • 注释
      • String
      • 面向对象思想
      • Object
      • 包
      • 访问权限修饰符
      • 初始化块
      • 接口
      • 内部类
      • 注解
      • 枚举
      • 集合框架
      • List
      • Map
      • 泛型
      • 迭代
      • IO与流
      • 序列化
      • 异常
      • Lambda
      • Stream流
      • Socket
      • 缓冲
      • 命名规范
      • 拆箱装箱
      • 值传递
      • 深拷贝
      • 反射
      • JVM
      • 并发编程基础
    • python
      • 并发编程
      • 环境管理
  • software_engineering
    • basic_concepts
      • 系统分析与设计概述
      • 规划
      • 需求分析与原型设计
      • 项目管理
      • 建模
      • 数据库设计
      • 架构
      • 配置管理
      • 测试管理
      • 安全
      • 编码原则
      • 微服务
      • 补充内容
    • software_testing
      • CMMI基础
      • PPQA与SQA
      • 软件测试基础
      • 黑盒测试
      • 白盒测试
      • 集成测试
      • 系统测试
      • 测开面试补充
由 GitBook 提供支持
在本页
  • 准备
  • 例子1
  • 例子2
在GitHub上编辑
  1. agent

处理 Tool Call error

准备

import os

# os.environ['HTTP_PROXY'] = 'http://127.0.0.1:10809'
# os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:10809'
os.environ['LANGSMITH_TRACING'] = 'true'
os.environ['LANGSMITH_ENDPOINT'] = 'https://api.smith.langchain.com'
os.environ['LANGSMITH_API_KEY'] = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
os.environ['LANGSMITH_PROJECT'] = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

例子1

首先,定义一个模拟天气工具,该工具对输入查询有一些隐藏的限制。此处的目的是模拟模型无法正确调用工具的真实情况:

from langchain_core.tools import tool


@tool
def get_weather(location: str):
    """Call to get the current weather."""
    if location == "san francisco":
        return "It's 60 degrees and foggy."
    elif location == "San Francisco":
        raise ValueError("Please lowercase the first letter of the place name")
    else:
        raise ValueError("Invalid input.")

接下来,设置 ReAct 代理的图形实现。此代理将一些查询作为输入,然后重复调用 tools,直到它有足够的信息来解析查询。我们将使用预构建的 ToolNode 来执行 called tools

from typing import Literal

from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode

tool_node = ToolNode([get_weather])

llm = ChatOpenAI(
    model="gpt-4o-mini"
)
model_with_tools = llm.bind_tools([get_weather])


def should_continue(state: MessagesState):
    messages = state["messages"]
    last_message = messages[-1]
    if last_message.tool_calls:
        return "tools"
    return END


def call_model(state: MessagesState):
    messages = state["messages"]
    response = model_with_tools.invoke(messages)
    return {"messages": [response]}


workflow = StateGraph(MessagesState)

# Define the two nodes we will cycle between
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)

workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue, ["tools", END])
workflow.add_edge("tools", "agent")

app = workflow.compile()
from IPython.display import Image, display

try:
    display(Image(app.get_graph().draw_mermaid_png()))
except Exception:
    # This requires some extra dependencies and is optional
    pass

当您尝试调用该工具时,您可以看到模型使用错误的输入调用该工具,从而导致工具引发错误。执行该工具的预构建 ToolNode 具有一些内置的错误处理功能,可以捕获错误并将其传递回模型,以便它可以重试:

for chunk in app.stream(
    {"messages": [("human", "what's the weather in San Francisco?")]}, stream_mode="values"
):
    chunk["messages"][-1].pretty_print()
================================ Human Message =================================

what's the weather in San Francisco?
================================== Ai Message ==================================
Tool Calls:
  get_weather (call_UUwHO9mcRUCLeQIXc9UHkURS)
 Call ID: call_UUwHO9mcRUCLeQIXc9UHkURS
  Args:
    location: San Francisco
================================= Tool Message =================================
Name: get_weather

Error: ValueError('Please lowercase the first letter of the place name')
 Please fix your mistakes.
================================== Ai Message ==================================
Tool Calls:
  get_weather (call_WSv60RptgWNgvkAt6WVGkGdV)
 Call ID: call_WSv60RptgWNgvkAt6WVGkGdV
  Args:
    location: san francisco
================================= Tool Message =================================
Name: get_weather

It's 60 degrees and foggy.
================================== Ai Message ==================================

The weather in San Francisco is 60 degrees and foggy.

在这个例子中,

  1. LLM 使用 San Francisco 作为参数查询天气

  2. 我们手动设置了一个陷阱,如果是首字母大写了,返回错误:Please lowercase the first letter of the place name

  3. LLM 能够理解错误并改正

例子2

在这个例子中,

  1. LLM 能够准确理解参数限制

    1. 如果第一次理解不了,pydantic 输出的 error 也能帮助 LLM 修改参数

  2. 我们手动设置了一个陷阱,topic 不能直接包含 "water"

  3. LLM 能够理解错误并改正

from langchain_core.output_parsers import StrOutputParser
from pydantic import BaseModel, Field


class HaikuRequest(BaseModel):
    topic: list[str] = Field(
        max_length=3,
        min_length=3,
    )


@tool
def master_haiku_generator(request: HaikuRequest):
    """Generates a haiku based on the provided topics."""
    model = ChatOpenAI(
        model="gpt-4o-mini",
    )
    chain = model | StrOutputParser()
    topics = ", ".join(request.topic)
    if "water" in topics:
        raise ValueError("topics should not appear 'water' directly")
    haiku = chain.invoke(f"Write a haiku about {topics}")
    return haiku


tool_node = ToolNode([master_haiku_generator])

model = ChatOpenAI(
    model="gpt-4o-mini",
)
model_with_tools = model.bind_tools([master_haiku_generator])


def should_continue(state: MessagesState):
    messages = state["messages"]
    last_message = messages[-1]
    if last_message.tool_calls:
        return "tools"
    return END


def call_model(state: MessagesState):
    messages = state["messages"]
    response = model_with_tools.invoke(messages)
    return {"messages": [response]}


workflow = StateGraph(MessagesState)

# Define the two nodes we will cycle between
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)

workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue, ["tools", END])
workflow.add_edge("tools", "agent")

app = workflow.compile()
# example with a single tool call
for chunk in app.stream(
    {"messages": [("Write me an incredible haiku about water.")]}, {"recursion_limit": 10}, stream_mode="values"
):
    chunk["messages"][-1].pretty_print()
================================ Human Message =================================

Write me an incredible haiku about water.
================================== Ai Message ==================================
Tool Calls:
  master_haiku_generator (call_RAwVONZkaBV1kcg6S0EvVacq)
 Call ID: call_RAwVONZkaBV1kcg6S0EvVacq
  Args:
    request: {'topic': ['water', 'nature', 'tranquility']}
================================= Tool Message =================================
Name: master_haiku_generator

Error: ValueError("topics should not appear 'water' directly")
 Please fix your mistakes.
================================== Ai Message ==================================
Tool Calls:
  master_haiku_generator (call_rZRGP2DB9QJMtpdJBExYs8Ze)
 Call ID: call_rZRGP2DB9QJMtpdJBExYs8Ze
  Args:
    request: {'topic': ['flow', 'nature', 'tranquility']}
================================= Tool Message =================================
Name: master_haiku_generator

Gentle river bends,  
Whispers through the silent trees,  
Nature’s breath, pure peace.
================================== Ai Message ==================================

Here’s an incredible haiku about water:

Gentle river bends,  
Whispers through the silent trees,  
Nature’s breath, pure peace.

我们使用 pydantic 设置的参数限制,LLM 能看到

上一页temp下一页trick

最后更新于29天前

png