ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Langchain-Chatchat Agent 系统命令(Shell)工具源码解析:从 LangChain ShellTool 到工具注册与安全使用

Langchain-Chatchat Agent 系统命令(Shell)工具源码解析:从 LangChain ShellTool 到工具注册与安全使用 Langchain-Chatchat Agent 系统命令Shell工具源码解析从 LangChain ShellTool 到工具注册与安全使用【免费下载链接】Langchain-ChatchatLangchain-Chatchat原Langchain-ChatGLM基于 Langchain 与 ChatGLM, Qwen 与 Llama 等语言模型的 RAG 与 Agent 应用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain项目地址: https://gitcode.com/GitHub_Trending/la/Langchain-ChatchatLangchain-Chatchat 的 Agent 体系中内置了一个可让大模型直接执行系统命令的工具 ——shell。它以 LangChain 社区提供的ShellTool为底层执行引擎通过统一的自研工具装饰器regist_tool注册进工具注册表供 Agent 在多轮推理中选择调用。读完本文你将掌握该工具在chatchat-server中的完整实现链路定义 → 注册 → 参数校验 → 输出封装 → 检索调用并理解大模型驱动本地命令行执行背后必须重视的安全边界与配置前提。工具定位让 Agent 具备动手操作能力在 Langchain-Chatchat 的 Agent 应用场景中大模型除了能回答知识库检索类问题外还经常需要执行一些动作型任务查询系统信息、操作文件、运行脚本、检查运行环境等。shell工具正是为此设计——它接收一段 Shell 命令字符串在服务端本地子进程中执行并把命令输出结果返回给大模型作为其继续推理的观察Observation依据。该能力由工具工厂目录中独立文件封装路径为 libs/chatchat-server/chatchat/server/agent/tools_factory/shell.py。同目录下的calculate、arxiv、search_internet等工具共用同一套注册机制shell在其中承担的是偏计算环境操作的角色。核心函数shell 的完整源码解读当前仓库中shell工具的实际实现如下比文档描述更精简遵循统一工具规范# LangChain 的 Shell 工具 from langchain_community.tools import ShellTool from chatchat.server.pydantic_v1 import Field from .tools_registry import regist_tool from langchain_chatchat.agent_toolkits.all_tools.tool import ( BaseToolOutput, ) regist_tool(title系统命令) def shell(query: str Field(descriptionThe command to execute)): Use Shell to execute system shell commands tool ShellTool() return BaseToolOutput(tool.run(tool_inputquery))逐行拆解其职责组成作用regist_tool(title系统命令)自研装饰器将函数注册进全局工具注册表并为其设置面向人类用户的中文标题系统命令query: str Field(descriptionThe command to execute)通过 PydanticField声明工具入参及语义描述供大模型理解如何传参docstring: Use Shell to execute system shell commands当未显式提供 description 时regist_tool会把函数 docstring 归一化后作为工具的英文描述帮助 LLM 判断何时调用该工具tool ShellTool()实例化 LangChain 社区版 Shell 执行器tool.run(tool_inputquery)真正执行命令并拿到结果BaseToolOutput(...)对执行结果做统一封装兼顾字符串与结构化数据两种消费场景详见下文函数本身只有 6 行有效逻辑真正执行命令的是langchain_community.tools.ShellTool。它默认在服务端本地子进程中按 Shell 语法解释执行传入命令并汇总标准输出含错误信息作为返回字符串。因此该工具的语义等价于在部署 chatchat-server 的这台机器上执行一条 bash 命令其能力边界、安全风险都由这一点决定。注册机制regist_tool 与全局工具注册表shell函数本身不产生任何 Agent 可感知的副作用它之所以能出现在 Agent 的工具列表中依赖的是 tools_registry.py 中定义的两块基础设施1. 全局注册表_TOOLS_REGISTRY_TOOLS_REGISTRY {}这是一个模块级字典regist_tool的核心动作就是把工具实例写入该字典def _parse_tool(t: BaseTool): nonlocal description, title _TOOLS_REGISTRY[t.name] t # 以工具名shell为键入库 # 未显式传入 description 时使用函数 docstring 并折叠为单行 if not description: if t.func is not None: description t.func.__doc__ ... t.description .join(re.split(r\n\s*, description)) # 未显式传入 title 时自动由工具名生成人类可读标题如 Shell - Shell if not title: title .join([x.capitalize() for x in t.name.split(_)]) t.title title对shell而言入库后的工具对象名称即shell人类可读标题被显式指定为系统命令description 取自 docstringUse Shell to execute system shell commands。这些描述正是 ReAct/Structured-Chat 型提示词中你可以使用以下工具列表的来源直接决定大模型能否在正确时机选到它。2. 装饰器的两种调用形态regist_tool兼容 LangChaintool装饰器的有参/无参两种用法无参形态regist_tool(title系统命令)即shell的用法len(args) 0时返回wrapper由 wrapper 内部调用tool(...)再注册有参形态regist_tool(some_langchain_kwarg)直接构造BaseTool并注册。此外该模块还以兼容补丁的方式扩展了BaseTool开启Config.extra Extra.allow以支持title等扩展字段并重写了_parse_input/_to_args_and_kwargs使 Pydantic v1 风格Field定义的单参工具能够被正确解析执行。这意味着shell中query参数的声明方式与 LangChain 工具参数 schema 的自动推断是打通工作的具体解释见下一节。参数模型从文档中的 ShellInput 到自动推断的 Field关联文档描述了这样一个输入模型ShellInput类继承自BaseModel定义一个字符串属性query描述为一个能在 Linux 命令行运行的 Shell 命令用于数据验证和管理。它本质上是用 Pydantic 模型为工具入参加一层结构约束与校验确保进入执行层的一定是合法的命令字符串。对照当前仓库源码ShellInput这样的显式 args_schema 类在部分工具如带多个入参的工具中仍可见而shell的入参已被简化为query: str Field(descriptionThe command to execute)的内联写法。这种写法之所以可行是因为 tools_registry.py 在调用 LangChaintool装饰器时传入infer_schemaTrue默认值LangChain 会自动依据函数签名反推args_schemaquery字段的description会被填入生成 schema 的字段描述中。因此无论显式ShellInput还是内联Field传递给 Agent 的参数说明、由 LLM 生成的工具调用 JSON、到最终真正执行前的类型校验走的是同一条 pydantic 验证链路。这样设计也印证了文档中的结论该工具处理的是封装好的命令输入执行前先经过模型校验降低脏数据进入子进程的概率。返回值封装BaseToolOutput 的一体两用shell的返回被包装为BaseToolOutput其定义见 libs/chatchat-server/langchain_chatchat/agent_toolkits/all_tools/tool.pyLLM 要求工具输出必须是str因此BaseToolOutput实现了__str__在未指定 format 时直接返回str(self.data)即命令输出的字符串当工具被复用在需要结构化数据的地方时原始数据仍保留在data字段中可通过data_alias、formatjson或自定义格式化回调灵活呈现。对于shell工具BaseToolOutput(tool.run(tool_inputquery))意味着给 LLM 的就是命令输出的纯文本。若执行shell(echo Hello World)且ShellTool.run正常返回标准输出那么返回结果的字符串形态即为Hello World该输出随后作为 Observation 进入 Agent 的 scratchpad中间步骤记录驱动模型决定是继续调用工具还是产出最终答案。如何被加载与调用从 import 到 get_tool单看 shell.py 无法让工具活起来还需完成两步装配1. 模块级导入即注册。tools_factory/init.py 在包导入时逐条执行各工具模块的导入from .shell import shell由于regist_tool是模块顶层装饰器模块一被 importshell即被写入_TOOLS_REGISTRY。2. 运行时按需重载与读取。server/utils.py 提供了统一的获取入口def get_tool(name: str None) - Union[BaseTool, Dict[str, BaseTool]]: import importlib from chatchat.server.agent import tools_factory importlib.reload(tools_factory) # 重新导入确保最新注册生效 from chatchat.server.agent.tools_factory import tools_registry update_search_local_knowledgebase_tool() # 动态同步知识库搜索工具的描述 if name is None: return tools_registry._TOOLS_REGISTRY # 不带参数返回全部工具 else: return tools_registry._TOOLS_REGISTRY.get(name) # 按名取单个工具在实际 Agent 会话中系统会结合用户在 WebUI「模型配置」页针对当前对话模型勾选的工具集合从注册表中筛选出允许的BaseTool列表再注入到 Agent 的提示词模板与执行链中相关调用链与说明可参考 agents/all_tools_agent.py 中的available_tool_names逻辑以及 markdown_docs/server/agent/model_contain.md。因此即使工具已注册也只有当用户在 Agent 对话配置中显式允许它时大模型才有机会触发执行——这是第一道使用门槛。安全边界与使用建议务必阅读关联文档与本仓库代码都明确提示了该工具的高危属性本节作结构化总结1. 命令不可信即危险。shell底层执行等价于本地 bash一旦query来自恶意提示注入或不可信外部源可能导致任意命令执行。文档原文强调需要确保传入的query命令是安全的避免执行恶意代码。实践中应遵循仅在受信任的私有大模型环境中启用该工具不要把系统命令工具暴露给多租户、公网或不受控的最终用户对 LLM 输出的命令做额外校验阻断含重定向、管道、下载执行链等危险模式的输入。2. 执行结果即事实必须可观测。该函数执行结果取决于ShellTool的run方法如何实现也就是说本仓库无法在代码层兜底——如果底层run失败、权限不足或命令不存在返回的是错误输出而不是异常Agent 需要依赖该文本判断是否重试。生产环境中建议优先以最小权限账号运行 chatchat-server不使用 root结合容器/沙箱限制文件系统与网络访问范围若需要的是只读探测能力可考虑将其替换为白名单式受限工具仓库中的其他只读工具如 search_internet.py、search_local_knowledgebase.py 提供更安全的替代交互。3. 平台前提。从参数描述一个能在 Linux 命令行运行的 Shell 命令可知该工具面向类 Unix/Linux 运行环境设计其实际可用性依赖部署宿主机的 Shell 环境与命令集。小结shell工具是 Langchain-Chatchat Agent 工具体系中代码最简、能力最重的一个外层由regist_tool完成注册表登记与描述注入中层由 PydanticField/infer_schema完成参数 schema 生成与校验内层委托 LangChainShellTool在本地子进程执行最后用BaseToolOutput把执行文本回传给大模型。理解这条链路既能帮助你排查模型明明选了系统命令却执行失败的问题依次检查工具勾选、registry 加载、query 拼写与宿主权限也能在扩展同类自定义工具时直接复用同一套范式——只需像shell一样用regist_tool包一个入参明确的函数即可同类示例见 calculate.py。与此同时务必把安全边界放在能力之上系统命令工具只应出现在你能完全信任的 Agent 运行环境中。【免费下载链接】Langchain-ChatchatLangchain-Chatchat原Langchain-ChatGLM基于 Langchain 与 ChatGLM, Qwen 与 Llama 等语言模型的 RAG 与 Agent 应用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain项目地址: https://gitcode.com/GitHub_Trending/la/Langchain-Chatchat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表