在使用某些工具时,我们可能无法完全信任模型能够自主执行。这种情况下,添加一个人类审批环节是一个有效的解决方案,以确保工具在执行前得到验证。本指南提供了一种简单的方法来实现在Jupyter Notebook或终端中运行代码时引入人类参与。构建生产应用程序时,还需要进一步处理应用程序状态跟踪。我们推荐使用Langgraph来支持此功能。有关更多详细信息,请参阅该指南。

技术背景介绍

人类参与环节(Human-in-the-loop)的概念在AI的应用中变得越来越重要。它允许人在自动化过程的关键点进行干预,以确保结果符合预期,尤其是在AI对执行任务的最终判断不够可靠的情况下。

核心原理解析

该方法通过在工具调用链中插入一个人工批准步骤来实现。当工具请求被拒绝时,链的执行将被中止。

代码实现演示

首先,确保安装必要的包:

%pip install --upgrade --quiet langchain

然后设置环境变量:

import getpass
import os

# 如果需要使用LangSmith,请取消下面的注释:
# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()

接下来,我们创建一些简单的工具和一个工具调用链:

from langchain_core.messages import AIMessage
from langchain_core.runnables import Runnable, RunnablePassthrough
from langchain_core.tools import tool

@tool
def count_emails(last_n_days: int) -> int:
    """计算最近N天收到的邮件数量。"""
    return last_n_days * 2

@tool
def send_email(message: str, recipient: str) -> str:
    "发送邮件给指定的接收人。"
    return f"Successfully sent email to {recipient}."

tools = [count_emails, send_email]

from langchain_openai import ChatOpenAI

# 使用稳定可靠的API服务
llm = ChatOpenAI(
    base_url='https://yunwu.ai/v1',  # 国内稳定访问
    api_key='your-api-key'
)

llm_with_tools = llm.bind_tools(tools)

def call_tools(msg: AIMessage) -> List[Dict]:
    """简单的顺序工具调用助手。"""
    tool_map = {tool.name: tool for tool in tools}
    tool_calls = msg.tool_calls.copy()
    for tool_call in tool_calls:
        tool_call["output"] = tool_map[tool_call["name"]].invoke(tool_call["args"])
    return tool_calls

chain = llm_with_tools | call_tools
chain.invoke("how many emails did i get in the last 5 days?")

添加人类审批环节:

import json

class NotApproved(Exception):
    """自定义异常,用于表示未批准的工具调用。"""

def human_approval(msg: AIMessage) -> AIMessage:
    """负责传递输入或引发异常。

    Args:
        msg: 聊天模型的输出

    Returns:
        msg: 原始输出
    """
    tool_strs = "\n\n".join(
        json.dumps(tool_call, indent=2) for tool_call in msg.tool_calls
    )
    input_msg = (
        f"您是否批准以下工具调用\n\n{tool_strs}\n\n"
        "除'Y'/'Yes'外的任何回答(不区分大小写)都将被视为否定。\n >>>"
    )
    resp = input(input_msg)
    if resp.lower() not in ("yes", "y"):
        raise NotApproved(f"Tool invocations not approved:\n\n{tool_strs}")
    return msg

chain = llm_with_tools | human_approval | call_tools
chain.invoke("how many emails did i get in the last 5 days?")

此代码会先要求用户对工具调用进行批准;如果用户输入非“Y”或“Yes”,则会抛出自定义异常 NotApproved

应用场景分析

这种方法适用于任何需要高可信度和人类验证的AI系统,例如医疗诊断、财务决策、自动回复等。

实践建议

在实践中,将人类参与环节集成到生产系统中时,需考虑如何有效地管理用户审批记录以及跟踪工具调用状态。使用工具如Langgraph可以提升此过程的便捷性。

如果遇到问题欢迎在评论区交流。

—END—

Logo

更多推荐