langchain_community.tools.ShellTool
类是 LangChain 社区库中的一个工具类,用于执行 shell 命令,并集成到 LangChain 的工作流中。
本文基于 LangChain 0.3.x ,详细介绍 ShellTool
的定义、参数、方法和典型场景,并提供一个独立示例,展示如何使用 ShellTool
结合 ChatOpenAI
和 RunnableLambda
实现人工智能主题的终端命令执行,示例突出 ShellTool
在自然语言驱动的终端操作中的作用。参考了相关网页信息(如 ShellTool 文档) 以确保准确性。
langchain_community.tools.ShellTool
简介
ShellTool
是 LangChain 社区库中的一个工具类,继承自 langchain_core.tools.BaseTool
,用于在本地机器上运行 shell 命令(如 Bash 命令)。它通过自然语言输入生成并执行终端命令,适合需要与操作系统交互的场景。ShellTool
实现标准 Runnable 接口,支持 LCEL 链式操作,常用于代理(Agent)或工具调用工作流。
核心功能:
- 执行 shell 命令(如
ls
、curl
)并返回输出。 - 支持命令验证和用户确认,增强安全性。
- 集成到 LCEL 链,支持与其他 Runnable 组合。
- 提供同步和异步调用,适配不同场景。
适用场景:
- 通过自然语言执行终端操作(如文件管理、系统查询)。
- 在代理中实现自动化任务(如下载文件、检查系统状态)。
- 结合 LLM 处理动态生成的命令。
- 构建需要与操作系统交互的智能应用。
注意:
与其他工具对比:
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
- 参数:
name
(str
):工具名称,默认为"terminal"
。description
(str
):工具描述,动态包含平台(如"Run shell commands on this Linux machine."
)。args_schema
(Type[BaseModel]
):输入参数模式,默认为ShellInput
,定义命令格式。ask_human_input
(bool
):是否在执行命令前要求用户确认(y/n),默认为False
。process
(Any
):Bash 进程实例,默认为BashProcess
(需langchain-experimental
)。**kwargs
:其他参数,如callbacks
(回调函数)、metadata
(元数据)。
- 功能:
- 初始化 Bash 进程(
BashProcess
)以运行命令。 - 验证输入命令(通过
ShellInput
)。 - 若
ask_human_input=True
,提示用户确认。 - 支持 LCEL 管道(
|
)和代理集成。
- 初始化 Bash 进程(
初始化示例
from langchain_community.tools import ShellTool
shell_tool = ShellTool(
name="terminal",
ask_human_input=True
)
ShellInput
定义
ShellInput
是 ShellTool
的输入模式:
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 命令。
- 输入:
input
(str | Dict
):命令字符串或字典(如{"commands": ["ls"]}
)。config
(Optional[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__
(已弃用)
使用方式
以下是使用 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
结合 ChatOpenAI
和 RunnableLambda
实现人工智能主题的终端命令执行。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 默认无安全限制,请在沙箱环境中运行!
代码说明
- LLM 初始化:
- 使用
ChatOpenAI
调用gpt-3.5-turbo
,设置temperature=0.7
。
- 使用
- ShellTool 初始化:
- 设置
ask_human_input=True
,要求用户确认命令。
- 设置
- 提示模板:
- 提示 LLM 生成 shell 命令。
- 工作流:
RunnableLambda
清理输入。- 组合
prompt
、llm
、parser
和shell_tool
形成 LCEL 链。
- 测试:
- 测试两个任务:列出文件(
ls
)、显示路径(pwd
)。 - 显示任务、命令和输出,展示命令执行流程。
- 测试两个任务:列出文件(
- 错误处理:
- 使用
try-except
捕获 API 或工具错误。
- 使用
- 警告:
运行要求:
- 有效的 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 或自定义实现)。
注意事项
- 安全风险:
- 依赖安装:
- 需
langchain-experimental
:pip install langchain-experimental
- 验证
BashProcess
:from langchain_experimental.llm_bash.bash import BashProcess
- 需
- 平台兼容性:
- 性能优化:
- 异步调用:使用
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}")])
- 异步调用:使用
- 错误调试:
- 命令失败:
- 检查命令:
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 命令的强大工具,核心功能包括:
- 定义:运行终端命令,支持自然语言生成。
- 初始化:通过
name
、ask_human_input
等配置。 - 常用方法:
invoke
(同步)、ainvoke
(异步)。 - 适用场景:自动化终端任务、代理集成。