首页
/ Gradio 应用接入 LLM Agent:用 gradio_tools 把任意 Gradio 应用封装为大模型工具

Gradio 应用接入 LLM Agent:用 gradio_tools 把任意 Gradio 应用封装为大模型工具

2026-09-08 14:47:32作者:伍希望

大语言模型(LLM)擅长理解与生成语言,但缺乏调用外部能力的手段;如果把模型无法直接完成的任务(如语音转写、图片生成、OCR)封装成"工具",交给 Agent 按需调用,就能显著扩展模型的行动边界。本篇技术指南以官方文档 guides/09_gradio-clients-and-lite/04_gradio-and-llm-agents.md 为骨架,讲解如何借助 gradio_tools 库把任何 Gradio 应用转成一个可供 LLM Agent 使用的工具,并深入封装自建工具所需的 GradioTool 抽象接口与底层 gradio_client 调用链。读完你将掌握:端到端装配一个可自主编排多工具的长链 Agent、为任意 Gradio 应用手写一个 LLM 工具、并理解 create_job / postprocess / fn_index 等关键概念背后的实现原理。

背景:Agent 与 Gradio 为何能互补

什么是 Agent

一个 LangChain Agent,本质上是"一个能够自主决定用哪些工具来完成任务的 LLM":它接收用户输入,从手头可用的一组工具中做选择、调用工具、读取工具返回结果,再继续推理直至产出最终答案。工具的描述(description)就是 Agent 的"目录"——它决定模型在什么场景下该选哪把工具。Gradio 恰好在生态中沉淀了大量开箱即用的机器学习应用,二者结合自然顺理成章。

Gradio 在其中扮演什么角色

Gradio 是构建、分享机器学习 Web 应用的 Python 框架(本仓库即其官方实现)。生态中已部署着大量功能各异的 Gradio Space 与自托管应用——语音识别、图像生成、OCR、视频合成等应有尽有。借助 gradio_client,任何 Gradio 应用都可以被当作 HTTP API 调用(参见 client/python/README.md 与姊妹篇指南 Getting Started with the Gradio Python client)。因此,只要把"调用 Gradio API"这件事封装成一个 Agent 能看懂的工具,LLM 就间接拥有了访问这些外部 AI 能力的手段。

gradio_tools 端到端示例:让 Agent 自主编排多把工具

文档中最核心的演示场景是:Agent 收到一条复合指令——"生成一张狗狗踩滑板的照片,但请先帮我把提示词优化一下;随后请为生成图配上一句说明,再用优化后的提示词生成一段视频"。注意,全程没有显式告诉 Agent 该用哪把工具、按什么顺序用,全靠模型自己编排。

该示例一共用到四把 gradio_tools 内置工具:

  • StableDiffusionPromptGeneratorTool:为 stable diffusion 优化提示词;
  • StableDiffusionTool:根据提示词生成图片;
  • ImageCaptioningTool:为生成的图片生成文字描述;
  • TextToVideoTool:根据提示词合成视频。

完整代码如下(来自关联文档):

import os

if not os.getenv("OPENAI_API_KEY"):
    raise ValueError("OPENAI_API_KEY must be set")

from langchain.agents import initialize_agent
from langchain.llms import OpenAI
from gradio_tools import (StableDiffusionTool, ImageCaptioningTool, StableDiffusionPromptGeneratorTool,
                          TextToVideoTool)

from langchain.memory import ConversationBufferMemory

llm = OpenAI(temperature=0)
memory = ConversationBufferMemory(memory_key="chat_history")
tools = [StableDiffusionTool().langchain, ImageCaptioningTool().langchain,
         StableDiffusionPromptGeneratorTool().langchain, TextToVideoTool().langchain]


agent = initialize_agent(tools, llm, memory=memory, agent="conversational-react-description", verbose=True)
output = agent.run(input=("Please create a photo of a dog riding a skateboard "
                          "but improve my prompt prior to using an image generator."
                          "Please caption the generated image and create a video for it using the improved prompt."))

这个示例有几个值得注意的工程细节:

  1. 环境变量前置校验:代码在导入任何 LLM 相关模块前先检查 OPENAI_API_KEY 是否已设置,避免运行中途才报出底层 API 鉴权错误。实际运行前请确保 OPENAI_API_KEY 已导出,并安装好 gradio_toolslangchain 及对应 LLM 依赖。
  2. .langchain 属性:每把工具实例通过 .langchain 暴露出可供 LangChain 直接识别的工具形态,再以列表形式交给 initialize_agent。模型会在推理中自行决策调用哪把、先调谁后调谁。
  3. 会话记忆ConversationBufferMemory(memory_key="chat_history") 配合 agent="conversational-react-description",让 Agent 能基于多轮对话历史做连续推理,而不是每轮"失忆"。
  4. 长链协同:PromptGenerator → StableDiffusion → ImageCaptioning/TextToVideo 的级联在本例中由模型自主发起,体现"工具化"的真正价值——模型能力通过工具组合被成倍放大。

指南同时指出,gradio_tools 仓库内置了一批开箱即用的预置工具(完整清单见其仓库 README),并在首章代码中演示了其中四把。若内置工具无法覆盖你的需求,也可以非常容易地封装自己的工具——这正是下一节的核心。

GradioTool 抽象:自定义工具的标准接口

gradio_tools 的核心抽象是 GradioTool。它继承 LangChain 的 BaseTool,只要开发者实现一组标准接口,就能把自己的 Gradio 应用变成一把 LLM 工具。文档给出的骨架如下:

class GradioTool(BaseTool):

    def __init__(self, name: str, description: str, src: str) -> None:

    @abstractmethod
    def create_job(self, query: str) -> Job:
        pass

    @abstractmethod
    def postprocess(self, output: Tuple[Any] | Any) -> str:
        pass

按文档的说明,实现一把工具需要满足以下要求(这也是实现层面最值得逐条咀嚼的部分):

  1. name(工具名):LLM 在推理中据以指代这把工具的唯一标识,应简洁、无歧义。
  2. description(工具描述)——至关重要:Agent 完全依靠 description 来决定何时调用哪把工具。务必精确定义工具的职责,并且给出输入与输出分别长什么样的示例,例如"输入应是图片内容的文字描述,输出是一个图片文件的路径"。描述含糊,模型就会选错工具或用错参数。
  3. src(Gradio 应用地址):既可以是完整 URL,也可以是 Hugging Face Space ID(如 freddyaboulton/calculator)。gradio_tools 会依据该值创建一个 gradio client 实例,通过其 API 协议与上游应用通信。此前提是:上游 Gradio 应用本身要能被 client 解析并暴露可调用的接口。
  4. create_job(query):给定一个字符串输入,解析后返回一个来自 client 的 Job。大多数场景下,只需把字符串透传给 client 的 submit 函数即可;更复杂的输入解析(如"从一段话中抽取多个槽位值")也可在此完成。
  5. postprocess(output):拿到 Job 结果后,将其转换成 LLM 可以展示给用户的字符串。Gradio 组件的原生输出形态(文件路径、元组、对象等)通常不适合直接"投喂"给文本模型,这一步负责做收敛与格式化。
  6. (可选)_block_input(gr) / _block_output(gr):某些框架(文档中举例 MiniChain 这类需要感知组件类型的库)可能要求了解工具底层 Gradio 的输入/输出组件类型。默认实现会返回 gr.Textbox();如需更精确的类型信息,可自行覆写这两个方法。注意 gr 参数是 import gradio as gr 得到的 gradio 模块对象,由 GradioTool 父类自动导入并注入,无需自己 import。

可以看到,设计哲学是"薄封装":工具类只需告诉系统(名字、描述、地址)以及两头(怎么发起调用、怎么把结果变成文本),中间的全部通信由 gradio_client 完成。

实例解读:StableDiffusionTool

文档以图片生成工具为范例,给出了 gradio_tools 内置 StableDiffusionTool 的参考实现(注意示例中导入写法 from gradio_tool import GradioTool 与上下文 from gradio_tools import ... 略有出入,实际使用时请以所安装的 gradio_tools 包公开的导入路径为准):

from gradio_tool import GradioTool
import os

class StableDiffusionTool(GradioTool):
    """Tool for calling stable diffusion from llm"""

    def __init__(
        self,
        name="StableDiffusion",
        description=(
            "An image generator. Use this to generate images based on "
            "text input. Input should be a description of what the image should "
            "look like. The output will be a path to an image file."
        ),
        src="gradio-client-demos/stable-diffusion",
        token=None,
    ) -> None:
        super().__init__(name, description, src, token)

    def create_job(self, query: str) -> Job:
        return self.client.submit(query, "", 9, fn_index=1)

    def postprocess(self, output: str) -> str:
        return [os.path.join(output, i) for i in os.listdir(output) if not i.endswith("json")][0]

    def _block_input(self, gr) -> "gr.components.Component":
        return gr.Textbox()

    def _block_output(self, gr) -> "gr.components.Component":
        return gr.Image()

文档对本实现的注解非常值得逐条对照源码理解:

  1. self.client 属性:所有 GradioTool 实例都自带一个指向底层应用的 gradio client,create_job 中使用的正是它。映射到本仓库,self.client 就是 gradio_client/client.py 中的 Client 类实例——其 __init__ 接收 src(Space 名或完整 URL)、token(访问私有 Space)、authdownload_filesssl_verify 等参数,随后探测应用配置与协议并完成端到端握手。
  2. create_job 只是把参数透传给 submitself.client.submit(query, "", 9, fn_index=1) 中,query 是用户提示词,""9 分别是硬编码的负面提示词与采样数量。从本仓库 Client.submit 的实现 看,submit 在后台线程中发起调用并立刻返回一个 Jobfn_index 用于在应用存在多个 API 端点时按索引选取目标端点,见其 docstring;predict 则是等价的阻塞式调用,位于同文件更早处)。文档特别提醒:后续版本完全可以让工具解析输入串中的这些附加参数,而不必硬编码。
  3. postprocess 取回第一张图:Stable Diffusion Space 的 gallery 会返回一组图片,此方法借助 os 模块遍历输出目录,过滤掉 .json 后缀(协议元数据文件),返回第一张图片的完整本地路径——这正是要交给 LLM 的字符串形态。
  4. _block_input / _block_output:声明该工具底层分别是文本输入与图片输出,为需要组件类型感知的第三方框架提供准确信息。

顺带一提,本仓库的 demo/stable-diffusion/run.py 就是一个可在本地起服务的 Stable Diffusion 演示应用:它把提示词、采样数、步数、引导系数(Guidance Scale)、随机种子暴露为 UI 控件,生成结果输出到 gr.Gallery。该文件验证了两点:其一,任何此类应用都能按"API 端点"被 client 寻址调用;其二,submit(query, "", 9, fn_index=1) 中逐位置传参的方式,本质上对应着上游应用某个端点按序暴露的参数(本工具额外依赖示例托管 Space 自身的布局,因此 fn_index=1 指向该托管应用的特定端点)。

链路复盘:一条用户指令如何穿越五层

把上面的代码串起来,一条完整指令的运行链路是:

  1. 用户把复合任务交给 Agent(LLM);
  2. LLM 依据各工具的 description 决定调用顺序(如先 PromptGenerator 再 StableDiffusion);
  3. 工具实例的 create_job 通过 gradio_client.Client.submit() 向远程 Gradio 应用发起请求,得到后台运行的 Jobsubmit 非阻塞、返回后即可继续,符合 Agent 多步推理的节奏;Jobclient.py 中实现,其 result() 会阻塞等待结果返回);
  4. 远程 Gradio 应用完成推理后,postprocess 把原生输出(文件、元组、对象)收敛成字符串;
  5. LLM 拿到字符串继续推理,最终汇总成面向用户的自然语言答案。

在这一链路里,gradio_client 是本仓库真正落地通信协议的模块:例如 Job 的状态轮询依赖 Status 枚举与 StatusUpdate(定义见 gradio_client/utils.py),view_api() 则能打印/返回端点签名辅助调试(见 client.py 的 view_api 实现)。想进一步了解 client 的能力边界(predict/submit/回调/会话态等),可阅读指南 Getting Started with the Gradio Python client

适用范围与版本演进提示

  • 本文所复现的 Agent 组装代码(from langchain.llms import OpenAIinitialize_agent(...)agent="conversational-react-description")对应的是文档撰写时期 LangChain 的 API 形态。LangChain 的模块划分与 Agent 构造方式随版本迭代变化较大,若按原文运行遇到导入错误,请以你所安装的 langchain 版本为准调整(例如新版将 LLM 实现迁移至独立的 langchain-openai 等包,并提供新的 Agent 构造入口)。
  • gradio_tools 是独立于本仓库的第三方库,其工具封装层面依赖的"应用即 API"能力则由本仓库的 gradio_client 提供;确保本地 gradio_client 为较新版本,可避免协议兼容问题。
  • GradioTool 的接口契约(含可选方法)并不绑定某个具体 Agent 框架,它同样适用于 MiniChain 等需要组件类型信息的框架,只不过这些框架会额外调用 _block_input / _block_output

结语

如文档结语所言,借助 gradio_tools,你可以让自己的 LLM 拥有访问生态中大量在运行的 Gradio Space 的能力——先写好 GradioTool 的六个要点(名字、精准描述、应用地址、create_jobpostprocess,以及可选的组件类型声明),再把它加入 Agent 的武器库即可。本仓库侧的重点始终是 gradio_client 这条"翻译官"链路:它是工具实例与远端应用之间的唯一通信通道,理解了 Client.submit / Job / fn_index 的语义,你写的每一个新工具就都能精准命中上游应用的 API。文档也欢迎开发者将自己实现的工具提交回 gradio_tools 仓库,让更多 Agent 共享这些能力。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
858
1.35 K
docsdocs
暂无描述
Markdown
899
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
923
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.83 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
532
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
524
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
393