大型语言模型 (LLMs) 非常令人印象深刻,但如果我们能赋予它们完成专业任务的技能,它们会变得更加强大。
gradio_tools 库可以将任何 Gradio 应用程序转变为代理可以使用的工具来完成其任务。例如,一个LLM可以使用 Gradio 工具来转录它在线找到的语音记录,然后为您总结。或者它可以使用不同的 Gradio 工具对您 Google Drive 上的文档应用 OCR,然后回答关于它的问题。
本指南将展示您如何使用 gradio_tools
授权您的LLM代理访问世界上托管的尖端 Gradio 应用程序。尽管 gradio_tools
与多个代理框架兼容,但我们将在本指南中重点介绍 Langchain 代理。
一些背景
什么是代理?
LangChain 代理是一个大型语言模型(LLM),它接受用户输入并根据使用其多种工具之一报告输出。
什么是 Gradio?
Gradio 是构建机器学习 Web 应用程序并与世界分享的事实标准框架 - 全部只用 python!🐍
gradio_tools - 一个端到端的例子
要开始使用 gradio_tools
,你所需要做的就是导入并初始化你的工具,然后将它们传递给 langchain 代理!
在以下示例中,我们导入 StableDiffusionPromptGeneratorTool
来为稳定扩散创建一个好的提示,导入 StableDiffusionTool
来用我们改进的提示创建一个图像,导入 ImageCaptioningTool
来为生成的图像添加标题,以及导入 TextToVideoTool
来从提示创建视频。
然后我们告诉我们的代理创建一张狗在滑板上的图片,但请提前改进我们的提示。我们还要求它为生成的图像添加标题并为其创建视频。代理可以决定使用哪个工具,而无需我们明确告知。
import os
# 检查环境变量中是否设置了OPENAI_API_KEY,如果没有设置则抛出错误
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
# 导入Gradio Tools中包含的工具
from gradio_tools import (StableDiffusionTool, ImageCaptioningTool, StableDiffusionPromptGeneratorTool,
TextToVideoTool)
from langchain.memory import ConversationBufferMemory
# 初始化OpenAI LLM(大型语言模型)实例,温度参数设置为0
llm = OpenAI(temperature=0)
# 初始化会话缓冲记忆体,用于存储聊天历史
memory = ConversationBufferMemory(memory_key="chat_history")
# 初始化各种Gradio工具,并将它们转换为langchain格式
tools = [StableDiffusionTool().langchain, ImageCaptioningTool().langchain,
StableDiffusionPromptGeneratorTool().langchain, TextToVideoTool().langchain]
# 使用提供的工具、LLM实例和记忆体初始化代理,并设置代理的模式为"conversational-react-description"
# 同时开启详细输出(verbose=True)
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."))
您会注意到我们正在使用一些随 gradio_tools
附带的预构建工具。请查看此文档以获取随 gradio_tools
附带的工具的完整列表。如果您想使用当前不在 gradio_tools
中的工具,添加您自己的工具非常容易。下一节将会介绍这方面的内容。
gradio_tools - 创建您自己的工具
核心抽象是 GradioTool
,只要您实现了一个标准接口,就可以为您的LLM定义一个新工具:
from abc import ABC, abstractmethod
from typing import Any, Tuple
class GradioTool(ABC):
"""
定义一个抽象基类,表示Gradio工具的通用结构。
"""
def __init__(self, name: str, description: str, src: str) -> None:
"""
初始化Gradio工具。
:param name: 工具的名称。
:param description: 工具的描述。
:param src: 工具的来源或识别信息。
"""
self.name = name # 工具名称
self.description = description # 工具描述
self.src = src # 工具来源信息
@abstractmethod
def create_job(self, query: str) -> 'Job':
"""
根据给定的查询创建一个工作任务。
:param query: 查询字符串。
:return: 返回一个Job对象。
"""
pass
@abstractmethod
def postprocess(self, output: Tuple[Any] | Any) -> str:
"""
对工作任务的输出进行后处理。
:param output: 工作任务产生的原始输出。
:return: 返回处理后的输出字符串。
"""
pass
要求如下:
您工具的名称
工具的描述。这一点至关重要!代理根据工具的描述来决定使用哪个工具。请确保描述准确,并且要包括工具输入和输出应该是什么样的示例。
Gradio 应用程序的网址或空间 id,例如
freddyaboulton/calculator
。根据这个值,gradio_tool
将创建一个 gradio 客户端实例通过 API 查询上游应用程序。如果您不熟悉它,请确保点击链接并了解更多关于 gradio 客户端库的信息。创建工作 - 给定一个字符串,这个方法应该解析该字符串并从客户端返回一个工作。大多数情况下,这就像将字符串传递给客户端的
submit
函数一样简单。更多关于创建工作的信息在这里后处理 - 根据工作的结果,将其转换为LLM可以向用户显示的字符串。
可选 - 一些库,例如 MiniChain,可能需要关于工具使用的底层 gradio 输入和输出类型的一些信息。默认情况下,这将返回 gr.Textbox(),但如果您想提供更准确的信息,请实现工具的
_block_input(self, gr)
和_block_output(self, gr)
方法。gr
变量是 gradio 模块(import gradio as gr
的结果)。它将由GradiTool
父类自动导入,并传递给_block_input
和_block_output
方法。
就是这样!
一旦您创建了工具,请向 gradio_tools
仓库提交一个拉取请求!我们欢迎所有的贡献。
示例工具 - 稳定扩散
这是作为示例的 StableDiffusion 工具的代码:
from gradio_tool import GradioTool
import os
import gradio as gr
class StableDiffusionTool(GradioTool):
"""
继承自GradioTool的定制工具类,用于调用基于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",
hf_token=None,
) -> None:
"""
初始化StableDiffusionTool实例。
:param name: 工具名称,默认为"StableDiffusion"。
:param description: 工具描述,描述了工具的功能。
:param src: 工具的来源信息或标识。
:param hf_token: Hugging Face Token,可选,用于访问某些受限API。
"""
super().__init__(name, description, src)
self.hf_token = hf_token # Hugging Face令牌
def create_job(self, query: str) -> 'Job':
"""
根据提供的文本描述提交一个生成图像的任务。
:param query: 文本描述,描述了所希望生成的图像内容。
:return: 返回一个Job对象,表示提交的任务。
"""
# 这里假设self.client是一个已经建立的客户端,用于提交任务
# 实际应用中需要根据实际情况实现client的提交函数
return self.client.submit(query, "", 9, fn_index=1)
def postprocess(self, output: str) -> str:
"""
对生成图像的任务输出进行后处理,返回图像文件的路径。
:param output: 任务输出的文件夹路径。
:return: 返回第一个非json文件的路径,通常是生成的图像文件。
"""
# 从输出的文件夹中筛选出非json文件,假设生成的图像不会以json为后缀
# 返回第一个这样的文件的路径
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":
"""
定义Gradio组件接口的输入部分。
:param gr: Gradio模块。
:return: 返回一个Gradio的文本框组件。
"""
return gr.Textbox()
def _block_output(self, gr) -> "gr.components.Component":
"""
定义Gradio组件接口的输出部分。
:param gr: Gradio模块。
:return: 返回一个Gradio的图像展示组件。
"""
return gr.Image()
这段代码展示了如何通过继承GradioTool
基类来创建一个具体的工具,StableDiffusionTool
,用于通过稳定扩散模型来根据文本描述生成图像。在__init__
方法中,除了调用基类的初始化之外,额外接收了hf_token
参数,用于可能需要的身份验证。create_job
方法假设有一个客户端对象负责提交生成图像的任务,而postprocess
方法则处理任务的输出,提取生成的图像路径。 _block_input
和_block_output
方法分别定义了输入和输出的Gradio界面组件,使得这个工具可以被集成到Gradio界面中,提供给用户直观的操作界面。
from gradio_tool import GradioTool
import os
import gradio as gr
class StableDiffusionTool(GradioTool):
"""
继承自GradioTool的定制工具类,用于调用基于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",
hf_token=None,
) -> None:
"""
初始化StableDiffusionTool实例。
:param name: 工具名称,默认为"StableDiffusion"。
:param description: 工具描述,描述了工具的功能。
:param src: 工具的来源信息或标识。
:param hf_token: Hugging Face Token,可选,用于访问某些受限API。
"""
super().__init__(name, description, src)
self.hf_token = hf_token # Hugging Face令牌
def create_job(self, query: str) -> 'Job':
"""
根据提供的文本描述提交一个生成图像的任务。
:param query: 文本描述,描述了所希望生成的图像内容。
:return: 返回一个Job对象,表示提交的任务。
"""
# 这里假设self.client是一个已经建立的客户端,用于提交任务
# 实际应用中需要根据实际情况实现client的提交函数
return self.client.submit(query, "", 9, fn_index=1)
def postprocess(self, output: str) -> str:
"""
对生成图像的任务输出进行后处理,返回图像文件的路径。
:param output: 任务输出的文件夹路径。
:return: 返回第一个非json文件的路径,通常是生成的图像文件。
"""
# 从输出的文件夹中筛选出非json文件,假设生成的图像不会以json为后缀
# 返回第一个这样的文件的路径
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":
"""
定义Gradio组件接口的输入部分。
:param gr: Gradio模块。
:return: 返回一个Gradio的文本框组件。
"""
return gr.Textbox()
def _block_output(self, gr) -> "gr.components.Component":
"""
定义Gradio组件接口的输出部分。
:param gr: Gradio模块。
:return: 返回一个Gradio的图像展示组件。
"""
return gr.Image()
关于这个实现的一些说明:
所有
GradioTool
的实例都有一个称为client
的属性,该属性指向底层的 gradio 客户端。这是你在create_job
方法中应该使用的。create_job
只是将查询字符串传递给客户端的submit
函数,并硬编码了一些其他参数,即负面提示字符串和指导比例尺。我们可以修改我们的工具,也接受来自输入字符串的这些值,在后续版本中。postprocess
方法简单地返回由稳定扩散空间创建的图库中的第一张图片。我们使用os
模块来获取图片的完整路径。
结论
你现在知道如何扩展你的LLM的能力,与成千上万的 gradio 空间一起在野外运行!再次,我们欢迎任何对 gradio_tools 库的贡献。我们很高兴看到大家构建的工具!