Integração Avançada de Ferramentas
Antes de iniciar este guia avançado, certifique-se de ter uma compreensão básica do processo de integração de ferramentas no Paragraph. Confira a Integração Rápida para uma visão geral rápida.
Interface de Ferramentas
Definimos uma série de métodos auxiliares na classe Tool para ajudar os desenvolvedores a construir ferramentas mais complexas rapidamente.
Retorno de Mensagens
O Paragraph suporta vários tipos de mensagens, como texto, link, imagem e arquivo BLOB. Você pode retornar diferentes tipos de mensagens para o LLM e os usuários por meio das seguintes interfaces.
Observe que alguns parâmetros nas interfaces a seguir serão apresentados nas seções posteriores.
URL da Imagem
Você só precisa passar o URL da imagem, e o Paragraph fará o download da imagem automaticamente e a retornará ao usuário.
def create_image_message(self, image: str, save_as: str = '') -> ToolInvokeMessage:
"""
criar uma mensagem de imagem
:param image: o URL da imagem
:return: a mensagem de imagem
"""Link
Se precisar retornar um link, você pode usar a seguinte interface:
def create_link_message(self, link: str, save_as: str = '') -> ToolInvokeMessage:
"""
criar uma mensagem de link
:param link: o URL do link
:return: a mensagem de link
"""Texto
Se precisar retornar uma mensagem de texto, você pode usar a seguinte interface:
def create_text_message(self, text: str, save_as: str = '') -> ToolInvokeMessage:
"""
criar uma mensagem de texto
:param text: o texto da mensagem
:return: a mensagem de texto
"""Arquivo BLOB
Se precisar retornar os dados brutos de um arquivo, como imagens, áudio, vídeo, PPT, Word, Excel, etc., você pode usar a seguinte interface.
- blob: os dados brutos do arquivo, do tipo bytes
- meta: os metadados do arquivo; se você souber o tipo do arquivo, é melhor passar um mime_type, caso contrário, o Paragraph usará octet/stream como tipo padrão.
def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '') -> ToolInvokeMessage:
"""
criar uma mensagem de blob
:param blob: o blob
:return: a mensagem de blob
"""Ferramentas Atalhos
Em aplicações de grande modelo, temos duas necessidades comuns:
- Resumir um texto longo antes de passá-lo ao LLM, evitando que o texto original seja muito longo para o LLM processar.
- O conteúdo obtido pela ferramenta é um link, e as informações da página web precisam ser rastreadas antes de serem retornadas ao LLM.
Para ajudar os desenvolvedores a implementar rapidamente essas duas necessidades, fornecemos as seguintes ferramentas de atalho:
Ferramenta de Resumo de Texto
Essa ferramenta recebe um user_id e o texto a ser resumido, retornando o texto resumido. O Paragraph usará o modelo padrão do espaço de trabalho atual para resumir o texto longo.
def summary(self, user_id: str, content: str) -> str:
"""
resumir o conteúdo
:param user_id: o id do usuário
:param content: o conteúdo
:return: o resumo
"""Ferramenta de Rastreamento de Página Web
Essa ferramenta recebe o link da página web a ser rastreada e um user_agent (que pode ser vazio), retornando uma string contendo as informações da página web.
def get_url(self, url: str, user_agent: str = None) -> str:
"""
obter url
""" o resultado rastreadoPool de Variáveis
Introduzimos um pool de variáveis na ferramenta para armazenar variáveis, arquivos, etc., gerados durante a operação da ferramenta. Essas variáveis podem ser usadas por outras ferramentas durante a execução da ferramenta.
A seguir, usaremos DallE3 e Vectorizer.AI como exemplos para demonstrar como usar o pool de variáveis.
DallE3
Primeiro, usamos o DallE3. Após criar a imagem, salvamos a imagem no pool de variáveis. O código é o seguinte:
from typing import Any, Dict, List, Union
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from base64 import b64decode
from openai import OpenAI
class DallE3Tool(BuiltinTool):
def _invoke(self,
user_id: str,
tool_paramters: Dict[str, Any],
) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
"""
invocar ferramentas
"""
client = OpenAI(
api_key=self.runtime.credentials['openai_api_key'],
)
# prompt
prompt = tool_paramters.get('prompt', '')
if not prompt:
return self.create_text_message('Por favor, insira um prompt')
# chamar openapi dalle3
response = client.images.generate(
prompt=prompt, model='dall-e-3',
size='1024x1024', n=1, style='vivid', quality='standard',
response_format='b64_json'
)
result = []
for image in response.data:
# Salvar todas as imagens no pool de variáveis por meio do parâmetro save_as. O nome da variável é self.VARIABLE_KEY.IMAGE.value. Se novas imagens forem geradas posteriormente, elas substituirão as anteriores.
result.append(self.create_blob_message(blob=b64decode(image.b64_json),
meta={ 'mime_type': 'image/png' },
save_as=self.VARIABLE_KEY.IMAGE.value))
return resultObserve que usamos self.VARIABLE_KEY.IMAGE.value como o nome da variável da imagem. Para que as ferramentas dos desenvolvedores cooperem entre si, definimos esta CHAVE. Você pode usá-la livremente, ou escolher não usá-la. Passar uma CHAVE personalizada também é aceitável.
Vectorizer.AI
Em seguida, usamos o Vectorizer.AI para converter o ícone PNG gerado pelo DallE3 em uma imagem vetorial. Vamos examinar as funções que definimos aqui. O código é o seguinte:
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter
from core.tools.errors import ToolProviderCredentialValidationError
from typing import Any, Dict, List, Union
from httpx import post
from base64 import b64decode
class VectorizerTool(BuiltinTool):
def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \
-> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
"""
Invocação da ferramenta, o nome da variável de imagem precisa ser passado aqui para que possamos obter a imagem do pool de variáveis
"""
def get_runtime_parameters(self) -> List[ToolParamter]:
"""
Sobrescreva a lista de parâmetros da ferramenta, podemos gerar dinamicamente a lista de parâmetros com base na situação atual no pool de variáveis, para que o LLM possa gerar o formulário com base na lista de parâmetros
"""
def is_tool_avaliable(self) -> bool:
"""
Se a ferramenta atual está disponível, se não houver imagem no pool de variáveis, então não precisamos exibir essa ferramenta, apenas retornar False aqui
""" Em seguida, vamos implementar essas três funções:
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter
from core.tools.errors import ToolProviderCredentialValidationError
from typing import Any, Dict, List, Union
from httpx import post
from base64 import b64decode
class VectorizerTool(BuiltinTool):
def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \
-> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
"""
invocar ferramentas
"""
api_key_name = self.runtime.credentials.get('api_key_name', None)
api_key_value = self.runtime.credentials.get('api_key_value', None)
if not api_key_name ou not api_key_value:
raise ToolProviderCredentialValidationError('Por favor, insira o nome e valor da chave da API')
# Obter o image_id, a definição de image_id pode ser encontrada em get_runtime_parameters
image_id = tool_paramters.get('image_id', '')
if not image_id:
return self.create_text_message('Por favor, insira o ID da imagem')
# Obter a imagem gerada pelo DallE do pool de variáveis
image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE)
if not image_binary:
return self.create_text_message('Imagem não encontrada, por favor, solicite ao usuário que gere a imagem primeiro.')
# Gerar a imagem vetorial
response = post(
'https://vectorizer.ai/api/v1/vectorize',
files={ 'image': image_binary },
data={ 'mode': 'test' },
auth=(api_key_name, api_key_value),
timeout=30
)
if response.status_code != 200:
raise Exception(response.text)
return [
self.create_text_message('O SVG vetorizado foi salvo como uma imagem.'),
self.create_blob_message(blob=response.content,
meta={'mime_type': 'image/svg+xml'})
]
def get_runtime_parameters(self) -> List[ToolParamter]:
"""
sobrescrever os parâmetros de tempo de execução
"""
# Aqui, sobrescrevemos a lista de parâmetros da ferramenta, definimos o image_id e configuramos sua lista de opções para todas as imagens no pool de variáveis atual. A configuração aqui é consistente com a configuração no yaml.
return [
ToolParamter.get_simple_instance(
name='image_id',
llm_description=f'o ID da imagem que você deseja vetorizar, \
e o ID da imagem deve ser especificado em \
{[i.name for i in self.list_default_image_variables()]}',
type=ToolParamter.ToolParameterType.SELECT,
required=True,
options=[i.name for i in self.list_default_image_variables()]
)
]
def is_tool_avaliable(self) -> bool:
# Apenas quando houver imagens no pool de variáveis, o LLM precisará usar essa ferramenta
return len(self.list_default_image_variables()) > 0Vale notar que, na verdade, não usamos o image_id aqui. Supomos que deve haver uma imagem no pool de variáveis padrão ao chamar essa ferramenta, então usamos diretamente image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE) para obter a imagem. Em casos em que as capacidades do modelo são fracas, recomendamos que os desenvolvedores façam o mesmo, o que pode melhorar efetivamente a tolerância a falhas e evitar que o modelo passe parâmetros incorretos.