Custom Tool

Mira cómo usar custom tools

Problema

Las funciones generalmente toman datos de entrada estructurados. Digamos que quieres que el LLM pueda llamar a la API de Airtable Create Record API, los parámetros del body tienen que estar estructurados de una manera específica. Por ejemplo:

"records": [
  {
    "fields": {
      "Address": "some address",
      "Name": "some name",
      "Visited": true
    }
  }
]

Idealmente, queremos que el LLM devuelva datos estructurados adecuadamente como esto:

{
  "Address": "some address",
  "Name": "some name",
  "Visited": true
}

Así podemos extraer el valor y analizarlo en el body necesario para la API. Sin embargo, instruir al LLM para que genere el patrón exacto es difícil.

Con los nuevos modelos de OpenAI Function Calling, ahora es posible. gpt-4-0613 y gpt-3.5-turbo-0613 están específicamente entrenados para devolver datos estructurados. El modelo elegirá de manera inteligente generar un objeto JSON que contenga los argumentos para llamar a esas funciones.

Tutorial

Objetivo: Hacer que el agent obtenga automáticamente el movimiento del precio de las acciones, recupere noticias relacionadas con las acciones y agregue un nuevo registro a Airtable.

Empecemos🚀

Crear Tools

Necesitamos 3 tools para lograr el objetivo:

  • Get Stock Price Movement

  • Get Stock News

  • Add Airtable Record

Get Stock Price Movement

Crea una nueva Tool con los siguientes detalles (puedes cambiarlos como desees):

  • Name: get_stock_movers

  • Description: Get the stocks that has biggest price/volume moves, e.g. actives, gainers, losers, etc.

La descripción es una parte importante ya que ChatGPT se basa en esto para decidir cuándo usar esta tool.

  • JavaScript Function: Vamos a usar la API Morning Star /market/v2/get-movers para obtener datos. Primero debes hacer clic en Subscribe to Test si aún no lo has hecho, luego copia el código y pégalo en JavaScript Function.

    • Agrega const fetch = require('node-fetch'); al principio para importar la librería. Puedes importar cualquier módulo integrado de NodeJS y librerías externas.

    • Retorna el result al final.

El código final debería ser:

const fetch = require('node-fetch');
const url = 'https://morning-star.p.rapidapi.com/market/v2/get-movers';
const options = {
	method: 'GET',
	headers: {
		'X-RapidAPI-Key': 'replace with your api key',
		'X-RapidAPI-Host': 'morning-star.p.rapidapi.com'
	}
};

try {
	const response = await fetch(url, options);
	const result = await response.text();
	console.log(result);
	return result;
} catch (error) {
	console.error(error);
	return '';
}

Ahora puedes guardarlo.

Get Stock News

Crea una nueva Tool con los siguientes detalles (puedes cambiarlos como desees):

  • Name: get_stock_news

  • Description: Get latest news for a stock

  • Input Schema:

    • Property: performanceId

    • Type: string

    • Description: id of the stock, which is referred as performanceID in the API

    • Required: true

Input Schema le indica al LLM qué debe devolver como objeto JSON. En este caso, esperamos un objeto JSON como el siguiente:

{ "performanceId": "SOME TICKER" }
  • JavaScript Function: Vamos a usar la API Morning Star /news/list para obtener los datos. Primero debes hacer clic en Subscribe to Test si aún no lo has hecho, luego copia el código y pégalo en JavaScript Function.

    • Agrega const fetch = require('node-fetch'); al principio para importar la librería. Puedes importar cualquier módulo integrado de NodeJS y librerías externas.

    • Retorna el result al final.

  • Luego, reemplaza el parámetro performanceId codificado en la URL: 0P0000OQN8 por la variable de propiedad especificada en Input Schema: $performanceId

  • Puedes usar cualquier propiedad especificada en Input Schema como variables en la JavaScript Function agregando el prefijo $ al principio del nombre de la variable.

Código final:

const fetch = require('node-fetch');
const url = 'https://morning-star.p.rapidapi.com/news/list?performanceId=' + $performanceId;
const options = {
	method: 'GET',
	headers: {
		'X-RapidAPI-Key': 'replace with your api key',
		'X-RapidAPI-Host': 'morning-star.p.rapidapi.com'
	}
};

try {
	const response = await fetch(url, options);
	const result = await response.text();
	console.log(result);
	return result;
} catch (error) {
	console.error(error);
	return '';
}

Ahora puedes guardarlo.

Add Airtable Record

Crea una nueva Tool con los siguientes detalles (puedes cambiarlos como desees):

  • Name: add_airtable

  • Description: Add the stock, news summary & price move to Airtable

  • Input Schema:

    • Property: stock

    • Type: string

    • Description: stock ticker

    • Required: true

    • Property: move

    • Type: string

    • Description: price move in %

    • Required: true

    • Property: news_summary

    • Type: string

    • Description: news summary of the stock

    • Required: true

ChatGPT devolverá un objeto JSON como este:

{ "stock": "SOME TICKER", "move": "20%", "news_summary": "Some summary" }
  • JavaScript Function: Vamos a usar Airtable Create Record API para crear un nuevo registro en una tabla existente. Puedes encontrar el tableId y baseId aquí. También necesitarás crear un token de acceso personal, encuentra cómo hacerlo aquí.

El código final debería verse como se muestra a continuación. Observa cómo pasamos $stock, $move y $news_summary como variables:

const fetch = require('node-fetch');
const baseId = 'your-base-id';
const tableId = 'your-table-id';
const token = 'your-token';

const body = {
	"records": [
		{
			"fields": {
				"stock": $stock,
				"move": $move,
				"news_summary": $news_summary,
			}
		}
	]
};

const options = {
	method: 'POST',
	headers: {
		'Authorization': `Bearer ${token}`,
		'Content-Type': 'application/json'
	},
	body: JSON.stringify(body)
};

const url = `https://api.airtable.com/v0/${baseId}/${tableId}`

try {
	const response = await fetch(url, options);
	const text = await response.text();
	return text;
} catch (error) {
	console.error(error);
	return '';
}

Ahora puedes guardarlo.

Deberías ver 3 tools creadas:

Crear Chatflow

Puedes usar la plantilla OpenAI Function Agent del marketplace, y reemplazar las tools con Custom Tool. Selecciona la tool que has creado.

Nota: OpenAI Function Agent solo soporta modelos 0613 actualmente.

Guarda el chatflow y comienza a probarlo. Para empezar, puedes intentar preguntar:

¿Qué acción tiene el mayor movimiento de precio hoy?

La acción que tiene el mayor movimiento de precio hoy es Overstock.com (OSTK) con un movimiento de precio del 17.47%.

Luego puedes hacer una pregunta de seguimiento para obtener las noticias de esa acción en particular:

¿Cuáles son las últimas noticias sobre esta acción que podrían haber causado el movimiento del precio?

Aquí están las últimas noticias sobre Overstock.com (OSTK) que podrían haber causado el movimiento del precio:

  1. Título: "Las acciones de Overstock se disparan tras la exitosa oferta de 21.5 millones por los activos de Bed Bath & Beyond" Fuente: MarketWatch Fecha de publicación: 22 de junio de 2023 Resumen: Las acciones de Overstock.com experimentaron un aumento significativo después de ganar exitosamente una oferta por los activos de Bed Bath & Beyond valorados en 21.5 millones.

  2. Título: "¿Pensando en operar opciones o acciones de Meta Platforms, Overstock.com, Walmart, Home Depot o United Parcel Service?" Fuente: PR Newswire Fecha de publicación: 22 de junio de 2023 Resumen: Este artículo de noticias discute las potenciales opciones de trading y acciones, incluyendo Overstock.com, que los inversores podrían considerar.

Ten en cuenta que estos artículos de noticias son solo para fines informativos y pueden no ser la única razón del movimiento del precio. Siempre se recomienda realizar una investigación y análisis exhaustivos antes de tomar cualquier decisión de inversión.

Por último, puedes pedirle a ChatGPT que agregue un nuevo registro a Airtable:

¿Puedes agregar un registro a Airtable con el ticker de la acción, el movimiento del precio y el resumen de noticias?

He agregado un registro a Airtable con los siguientes detalles:

Ticker de la acción: OSTK Movimiento del precio: 17.47% Resumen de noticias: Las acciones de Overstock.com experimentaron un aumento significativo después de ganar exitosamente una oferta por los activos de Bed Bath & Beyond valorados en $21.5 millones.

🎉🎉¡Voilà! ¡Así es como puedes crear tu propia custom tool y usarla con el OpenAI Function Agent!

Adicional

Pasar Session ID a la Function

Por defecto, la Function en custom tool tiene acceso a las siguientes configuraciones de flow:

$flow.sessionId 
$flow.chatId
$flow.chatflowId
$flow.input

A continuación se muestra un ejemplo de envío del sessionId a un webhook de Discord:

const fetch = require('node-fetch');
const webhookUrl = "https://discord.com/api/webhooks/1124783587267";
const content = $content; // capturado desde input schema
const sessionId = $flow.sessionId;

const body = {
	"content": `${mycontent} and the sessionid is ${sessionId}`
};

const options = {
	method: 'POST',
	headers: {
		'Content-Type': 'application/json'
	},
	body: JSON.stringify(body)
};

const url = `${webhookUrl}?wait=true`

try {
	const response = await fetch(url, options);
	const text = await response.text();
	return text;
} catch (error) {
	console.error(error);
	return '';
}

Pasar variables a la Function

En algunos casos, te gustaría pasar variables a la función de custom tool.

Por ejemplo, estás creando un chatbot que usa una custom tool. La custom tool está ejecutando una llamada HTTP POST y se necesita una API key para una solicitud autenticada exitosa. Puedes pasarla como una variable.

Por defecto, la Function en custom tool tiene acceso a las variables:

$vars.<variable-name>

Ejemplo de cómo pasar variables en Flowise usando API y Embedded:

async function query(data) {
    const response = await fetch(
        "http://localhost:3000/api/v1/prediction/<chatflow-id>",
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(data)
        }
    );
    const result = await response.json();
    return result;
}

query({
    "question": "Hey, how are you?",
    "overrideConfig": {
        "vars": {
            "apiKey": "abc"
        }
    }
}).then((response) => {
    console.log(response);
});

Ejemplo de cómo recibir las variables en custom tool:

const fetch = require('node-fetch');
const webhookUrl = "https://discord.com/api/webhooks/1124783587267";
const content = $content; // capturado desde input schema
const sessionId = $flow.sessionId;
const apiKey = $vars.apiKey;

const body = {
	"content": `${mycontent} and the sessionid is ${sessionId}`
};

const options = {
	method: 'POST',
	headers: {
		'Content-Type': 'application/json',
		'Authorization': `Bearer ${apiKey}`
	},
	body: JSON.stringify(body)
};

const url = `${webhookUrl}?wait=true`

try {
	const response = await fetch(url, options);
	const text = await response.text();
	return text;
} catch (error) {
	console.error(error);
	return '';
}

Sobrescribir Custom Tool

Los siguientes parámetros pueden ser sobrescritos

Parámetro
Descripción

customToolName

nombre de la tool

customToolDesc

descripción de la tool

customToolSchema

schema de la tool

customToolFunc

función de la tool

Ejemplo de una llamada API para sobrescribir parámetros de custom tool:

async function query(data) {
    const response = await fetch(
        "http://localhost:3000/api/v1/prediction/<chatflow-id>",
        {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(data)
        }
    );
    const result = await response.json();
    return result;
}

query({
    "question": "Hey, how are you?",
    "overrideConfig": {
        "customToolName": "example_tool",
        "customToolSchema": "z.object({title: z.string()})"
    }
}).then((response) => {
    console.log(response);
});

Importar Dependencias Externas

Puedes importar cualquier módulo integrado de NodeJS y librerías externas soportadas en la Function.

  1. Para importar cualquier librería no soportada, puedes agregar fácilmente el nuevo paquete npm al package.json en la carpeta packages/components.

cd Flowise && cd packages && cd components
pnpm add <your-library>
cd .. && cd ..
pnpm install
pnpm build
  1. Luego, agrega las librerías importadas a la variable de entorno TOOL_FUNCTION_EXTERNAL_DEP. Consulta https://github.com/FlowiseAI/FlowiseDocs/blob/main/esp/configuration/environment-variables.md#builtin-and-external-dependencies para más detalles.

  2. Inicia la aplicación

pnpm start
  1. Entonces podrás usar la librería recién agregada en la JavaScript Function así:

const axios = require('axios')

Mira cómo agregar dependencias adicionales e importar librerías

Last updated