【LangChain】langchain_community.tools.ShellTool 类:在本地机器上运行 shell 命令

langchain_community.tools.ShellTool 类是 LangChain 社区库中的一个工具类,用于执行 shell 命令,并集成到 LangChain 的工作流中。

本文基于 LangChain 0.3.x ,详细介绍 ShellTool 的定义、参数、方法和典型场景,并提供一个独立示例,展示如何使用 ShellTool 结合 ChatOpenAIRunnableLambda 实现人工智能主题的终端命令执行,示例突出 ShellTool 在自然语言驱动的终端操作中的作用。参考了相关网页信息(如 ShellTool 文档) 以确保准确性。


langchain_community.tools.ShellTool 简介

ShellTool 是 LangChain 社区库中的一个工具类,继承自 langchain_core.tools.BaseTool,用于在本地机器上运行 shell 命令(如 Bash 命令)。它通过自然语言输入生成并执行终端命令,适合需要与操作系统交互的场景。ShellTool 实现标准 Runnable 接口,支持 LCEL 链式操作,常用于代理(Agent)或工具调用工作流。

核心功能

  • 执行 shell 命令(如 lscurl)并返回输出。
  • 支持命令验证和用户确认,增强安全性。
  • 集成到 LCEL 链,支持与其他 Runnable 组合。
  • 提供同步和异步调用,适配不同场景。

适用场景

  • 通过自然语言执行终端操作(如文件管理、系统查询)。
  • 在代理中实现自动化任务(如下载文件、检查系统状态)。
  • 结合 LLM 处理动态生成的命令。
  • 构建需要与操作系统交互的智能应用。

注意

  • 默认无安全限制,可能执行危险命令(如 rm -rf /),需谨慎使用,建议在沙箱环境中运行。
  • 需安装 langchain-experimental 以支持 BashProcess

与其他工具对比

  • ShellTool:执行 shell 命令,适合终端操作。
  • PythonREPLTool:运行 Python 代码,适合编程任务。
  • 自定义工具:通过 @tool 装饰器定义特定功能。

类定义和初始化

以下是 ShellTool 的定义,基于 LangChain 社区库源码(langchain_community/tools/shell/tool.py)和官方文档(ShellTool)。

类签名
class ShellTool(BaseTool):
    def __init__(
        self,
        name: str = "terminal",
        description: str = f"Run shell commands on this {platform} machine.",
        args_schema: Type[BaseModel] = ShellInput,
        ask_human_input: bool = False,
        process: Any = None,
        **kwargs: Any
    ) -> None
  • 参数
    • namestr):工具名称,默认为 "terminal"
    • descriptionstr):工具描述,动态包含平台(如 "Run shell commands on this Linux machine.")。
    • args_schemaType[BaseModel]):输入参数模式,默认为 ShellInput,定义命令格式。
    • ask_human_inputbool):是否在执行命令前要求用户确认(y/n),默认为 False
    • processAny):Bash 进程实例,默认为 BashProcess(需 langchain-experimental)。
    • **kwargs:其他参数,如 callbacks(回调函数)、metadata(元数据)。
  • 功能
    • 初始化 Bash 进程(BashProcess)以运行命令。
    • 验证输入命令(通过 ShellInput)。
    • ask_human_input=True,提示用户确认。
    • 支持 LCEL 管道(|)和代理集成。
初始化示例
from langchain_community.tools import ShellTool
shell_tool = ShellTool(
    name="terminal",
    ask_human_input=True
)
ShellInput 定义

ShellInputShellTool 的输入模式:

class ShellInput(BaseModel):
    commands: Union[str, List[str]] = Field(
        ..., description="List of shell commands to run. Deserialized using json.loads"
    )
  • 功能:验证输入为字符串或字符串列表。
  • 验证:若输入为单条命令,转换为列表。
  • 警告:默认发出安全警告,提示无保护措施。

工作原理

ShellTool 的运行逻辑如下:

  • 输入:接受 ShellInput 格式的命令(字符串或列表)。
  • 处理
    • 验证输入命令(通过 ShellInput)。
    • ask_human_input=True,提示用户确认(y/n)。
    • 使用 BashProcess 执行命令,捕获输出。
  • 输出:返回命令执行结果(字符串)。
  • 警告:每次运行发出安全警告,建议在沙箱环境使用。

在 LCEL 中的作用

  • 作为工具集成到代理或链中,处理自然语言生成的命令。
  • 支持与其他 Runnable(如 LLM)组合。

示例流程

shell_tool = ShellTool()
output = shell_tool.invoke("echo Hello World!")
# 输出: Hello World!\nreal\t0m0.000s\nuser\t0m0.000s\nsys\t0m0.000s

常用方法

ShellTool 继承自 langchain_core.tools.BaseTool,提供以下核心方法。

1. invoke
def invoke(self, input: Union[str, Dict], config: Optional[RunnableConfig] = None, **kwargs: Any) -> Any
  • 功能:同步调用,执行 shell 命令。
  • 输入
    • inputstr | Dict):命令字符串或字典(如 {"commands": ["ls"]})。
    • configOptional[RunnableConfig]):运行配置(如超时)。
  • 输出:命令执行结果(字符串)。
  • 示例
    result = shell_tool.invoke("ls")
    print(result)  # 输出: dir1\ndir2\nfile.txt
    
2. _run
def _run(self, commands: Union[str, List[str]], run_manager: Optional[CallbackManagerForToolRun] = None) -> str
  • 功能:核心执行方法,运行命令并返回输出。
  • 示例
    result = shell_tool._run(["echo Hello"])
    print(result)  # 输出: Hello
    
3. ainvoke / _arun
async def ainvoke(self, input: Union[str, Dict, ToolCall], config: Optional[RunnableConfig] = None, **kwargs: Any) -> Any
async def _arun(self, commands: Union[str, List[str]], run_manager: Optional[AsyncCallbackManagerForToolRun] = None) -> str
  • 功能:异步调用,执行命令。
  • 示例
    result = await shell_tool.ainvoke("ls")
    print(result)  # 输出: dir1\ndir2\nfile.txt
    
4. __call__ (已弃用)
  • 功能:使工具可调用,已弃用,推荐使用 invoke
  • 示例
    result = shell_tool("ls")  # 弃用
    

使用方式

以下是使用 ShellTool 的步骤。

1. 安装依赖
pip install --upgrade langchain langchain-openai langchain-experimental
2. 设置 OpenAI API 密钥(若使用 LLM)
export OPENAI_API_KEY="your-api-key"

或在代码中:

import os
os.environ["OPENAI_API_KEY"] = "your-api-key"
3. 初始化 ShellTool
from langchain_community.tools import ShellTool
shell_tool = ShellTool(ask_human_input=True)
4. 构建代理或链
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-3.5-turbo")
prompt = ChatPromptTemplate.from_template("生成命令: {input}")
chain = prompt | llm | shell_tool
5. 调用链
response = chain.invoke({"input": "列出当前目录文件"})
print(response)

使用 ShellTool 的示例

以下是一个独立示例,展示如何使用 ShellTool 结合 ChatOpenAIRunnableLambda 实现人工智能主题的终端命令执行。ShellTool 用于执行自然语言生成的 shell 命令,展示其在自动化任务中的作用。

准备环境

  • 获取 OpenAI API 密钥:OpenAI Platform
  • 设置环境变量:
    export OPENAI_API_KEY="your-api-key"
    
  • 安装依赖:
    pip install --upgrade langchain langchain-openai langchain-experimental
    

代码

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableLambda
from langchain_community.tools import ShellTool
from langchain_core.output_parsers import StrOutputParser

# 初始化 ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)

# 初始化 ShellTool
shell_tool = ShellTool(ask_human_input=True)

# 定义提示模板
prompt = ChatPromptTemplate.from_template(
    "你是一个终端命令专家,生成以下任务的 shell 命令:{input}\n命令:"
)

# 定义输出解析器
parser = StrOutputParser()

# 创建工作流
chain = (
    RunnableLambda(lambda x: x.strip()) | prompt | llm | parser | shell_tool
)

# 测试 ShellTool 和命令执行
print("测试 ShellTool 和命令执行工作流:")
try:
    tasks = [
        "列出当前目录中的文件",
        "显示当前工作目录路径"
    ]
    
    for task in tasks:
        print(f"\n输入任务: {task}")
        result = chain.invoke(task)
        print(f"命令输出: {result}")
except Exception as e:
    print(f"错误: {e}")

print("\n警告:ShellTool 默认无安全限制,请在沙箱环境中运行!")

输出示例(实际输出取决于系统和用户交互):

测试 ShellTool 和命令执行工作流:

输入任务: 列出当前目录中的文件
[ShellTool] 即将执行命令: ['ls']
请确认是否执行 (y/n): y
命令输出: dir1\ndir2\nfile.txt

输入任务: 显示当前工作目录路径
[ShellTool] 即将执行命令: ['pwd']
请确认是否执行 (y/n): y
命令输出: /home/user/project

警告:ShellTool 默认无安全限制,请在沙箱环境中运行!
代码说明
  1. LLM 初始化
    • 使用 ChatOpenAI 调用 gpt-3.5-turbo,设置 temperature=0.7
  2. ShellTool 初始化
    • 设置 ask_human_input=True,要求用户确认命令。
  3. 提示模板
    • 提示 LLM 生成 shell 命令。
  4. 工作流
    • RunnableLambda 清理输入。
    • 组合 promptllmparsershell_tool 形成 LCEL 链。
  5. 测试
    • 测试两个任务:列出文件(ls)、显示路径(pwd)。
    • 显示任务、命令和输出,展示命令执行流程。
  6. 错误处理
    • 使用 try-except 捕获 API 或工具错误。
  7. 警告
    • 提醒用户 ShellTool 的安全风险。

运行要求

  • 有效的 OpenAI API 密钥:
    export OPENAI_API_KEY="your-api-key"
    
  • 安装依赖:
    pip install --upgrade langchain langchain-openai langchain-experimental
    
  • 网络连接:访问 https://api.openai.com.
  • 支持 Bash 的环境(如 Linux、macOS;Windows 需 WSL 或自定义实现)。

注意事项

  1. 安全风险
    • ShellTool 默认无安全限制,可能执行危险命令,建议:
      • 启用 ask_human_input=True
        shell_tool = ShellTool(ask_human_input=True)
        
      • 在沙箱环境运行(如 Docker)。
    • 检查命令日志:
      print(shell_tool.invoke("ls"))
      
  2. 依赖安装
    • langchain-experimental
      pip install langchain-experimental
      
    • 验证 BashProcess
      from langchain_experimental.llm_bash.bash import BashProcess
      
  3. 平台兼容性
    • 默认支持 Linux 和 macOS(Darwin 检测为 MacOS)。
    • Windows 需自定义工具(如使用 subprocess)。
  4. 性能优化
    • 异步调用:使用 ainvoke
      result = await shell_tool.ainvoke("ls")
      
    • 批量处理:结合 abatch
      results = await shell_tool.abatch([{"commands": ["ls"]}, {"commands": ["pwd"]}])
      
    • 回调:添加运行时日志:
      shell_tool = ShellTool(callbacks=[lambda x: print(f"执行: {x}")])
      
  5. 错误调试
    • 命令失败
      • 检查命令:
        print(shell_tool.invoke("invalid_cmd"))
        
      • 验证 BashProcess 输出:
        from langchain_experimental.llm_bash.bash import BashProcess
        process = BashProcess()
        print(process.run(["ls"]))
        
    • API 错误
      • 检查密钥:
        print(os.environ.get("OPENAI_API_KEY"))
        
      • 增加超时:
        llm = ChatOpenAI(timeout=30)
        
    • 输入验证
      • 检查 ShellInput
        from langchain_community.tools.shell.tool import ShellInput
        print(ShellInput(commands=["ls"]).commands)
        

常见问题

Q1:如何增强 ShellTool 安全性?
A:启用用户确认并限制命令:

shell_tool = ShellTool(ask_human_input=True)
# 自定义验证
from langchain_community.tools.shell.tool import ShellInput
class SafeShellInput(ShellInput):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        for cmd in self.commands:
            if "rm -rf" in cmd:
                raise ValueError("危险命令被阻止")
shell_tool.args_schema = SafeShellInput

Q2:如何与代理结合?
A:使用 initialize_agent

from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")
agent = initialize_agent(
    tools=[shell_tool],
    llm=llm,
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)
agent.run("列出当前目录文件")

Q3:如何支持 Windows?
A:自定义工具使用 subprocess

from langchain_core.tools import tool
import subprocess
@tool
def windows_shell(command: str) -> str:
    """在 Windows 上运行 shell 命令"""
    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    return result.stdout + result.stderr

Q4:如何支持开源模型?
A:使用 ChatOllama

from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3")
chain = prompt | llm | parser | shell_tool
result = chain.invoke("列出当前目录文件")

总结

langchain_community.tools.ShellTool 是 LangChain 中用于执行 shell 命令的强大工具,核心功能包括:

  • 定义:运行终端命令,支持自然语言生成。
  • 初始化:通过 nameask_human_input 等配置。
  • 常用方法invoke(同步)、ainvoke(异步)。
  • 适用场景:自动化终端任务、代理集成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值