Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the acf domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6260

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the all-in-one-seo-pack domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6260

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-user-avatar domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6260

Warning: Cannot modify header information - headers already sent by (output started at /home/planetac/desa.planetachatbot.com/wp-includes/functions.php:6260) in /home/planetac/desa.planetachatbot.com/wp-content/plugins/all-in-one-seo-pack/app/Common/Meta/Robots.php on line 87

Warning: Cannot modify header information - headers already sent by (output started at /home/planetac/desa.planetachatbot.com/wp-includes/functions.php:6260) in /home/planetac/desa.planetachatbot.com/wp-includes/feed-rss2.php on line 8
Tutoriales - Planeta Chatbot https://desa.planetachatbot.com Comunidad de expertos en IA Conversacional Tue, 20 Aug 2024 16:48:05 +0000 es hourly 1 https://wordpress.org/?v=7.1 https://desa.planetachatbot.com/wp-content/uploads/2021/05/cropped-favicon-32x32.png Tutoriales - Planeta Chatbot https://desa.planetachatbot.com 32 32 Dominar el trading algorítmico con NextTrade https://desa.planetachatbot.com/dominar-trading-algoritmico-con-nexttrade/?utm_source=rss&utm_medium=rss&utm_campaign=dominar-trading-algoritmico-con-nexttrade https://desa.planetachatbot.com/dominar-trading-algoritmico-con-nexttrade/#respond Thu, 22 Aug 2024 06:00:35 +0000 https://desa.planetachatbot.com/?p=18375 Operar en los mercados financieros siempre ha sido una tarea en la que la precisión, la estrategia y la puntualidad desempeñan un papel fundamental. Con el avance de la tecnología, la negociación algorítmica se ha vuelto cada vez más sofisticada, ofreciendo a los operadores nuevas vías para mejorar sus estrategias y su rendimiento. En este […]

The post Dominar el trading algorítmico con NextTrade first appeared on Planeta Chatbot.

]]>
Operar en los mercados financieros siempre ha sido una tarea en la que la precisión, la estrategia y la puntualidad desempeñan un papel fundamental. Con el avance de la tecnología, la negociación algorítmica se ha vuelto cada vez más sofisticada, ofreciendo a los operadores nuevas vías para mejorar sus estrategias y su rendimiento. En este artículo, exploraremos NextTrade, una potente plataforma de negociación algorítmica reconstruida en Rust, que cubre sus características, las mejores prácticas y fragmentos de código detallados para que puedas empezar a planificar tu próxima operación con eficacia.

Introducción

Las plataformas de negociación algorítmica han evolucionado considerablemente en la última década. Sin embargo, con la creciente demanda de velocidad y fiabilidad, los desarrolladores se encuentran a menudo revisando los fundamentos de sus sistemas para asegurarse de que aprovechan las mejores herramientas y lenguajes disponibles. NextTrade, un proyecto que se sometió a una importante remodelación en Rust, es un modelo ejemplar de cómo las plataformas de negociación modernas pueden lograr un rendimiento y una fiabilidad superiores. En este artículo, te adentrarás en la trayectoria de NextTrade, sus componentes básicos y cómo puedes aprovechar tus capacidades para tus estrategias de negociación.

¿Por qué Rust para el comercio algorítmico?

Rust es un lenguaje de programación de sistemas que garantiza la seguridad de la memoria sin un recolector de basura, lo que lo convierte en la opción ideal para aplicaciones de rendimiento crítico como el trading algorítmico. He aquí por qué Rust cambia las reglas del juego para las plataformas de negociación:

  1. Rendimiento: El rendimiento de Rust es comparable al de C y C++, lo que es crucial para el comercio de alta frecuencia.
  2. Seguridad: Rust elimina errores comunes causados por errores de gestión de memoria, mejorando la fiabilidad de los algoritmos de negociación.
  3. Concurrencia: El modelo de propiedad de Rust facilita una programación concurrente segura y eficiente, esencial para manejar múltiples operaciones de trading simultáneamente.

Configuración de NextTrade

Para empezar con NextTrade, necesitas clonar el repositorio y configurar tu entorno de desarrollo.

git clone https://github.com/austin-starks/NextTrade.git
cd NextTrade
cargo build

Asegúrate de que tienes Rust instalado. Si no, puedes instalarlo usando rustup.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Configuración

NextTrade requiere configuración para conectarte a tu cuenta de brokerage y proveedores de datos de mercado. Esto se hace a través de un archivo de configuración, típicamente en config.toml.

[broker]
api_key = "your_api_key"
secret_key = "your_secret_key"
base_url = "https://api.broker.com"

[market_data]
provider = "provider_name"
api_key = "your_market_data_api_key"

Componentes principales

La arquitectura de NextTrade consta de varios componentes clave:

  1. Gestor de datos de mercado: Obtiene y procesa datos de mercado.
  2. Gestor de órdenes: Gestiona la creación, el envío y el seguimiento de órdenes.
  3. Motor de estrategias: Ejecuta estrategias de negociación basadas en datos de mercado.

Gestor de datos de mercado

El gestor de datos de mercado es responsable de recuperar y procesar datos en tiempo real. He aquí una versión simplificada de la implementación:

use reqwest::Client;
use serde::Deserialize;

#[derive(Deserialize)]
struct MarketData {
symbol: String,
price: f64,
}

async fn fetch_market_data(client: &Client, api_key: &str, symbol: &str) -> Result<MarketData, reqwest::Error> {
let url = format!("https://api.marketdata.com/v1/quote?symbol={}&api_key={}", symbol, api_key);
let resp = client.get(&url).send().await?.json::<MarketData>().await?;
Ok(resp)
}

#[tokio::main]
async fn main() {
let client = Client::new();
let api_key = "your_market_data_api_key";
match fetch_market_data(&client, api_key, "AAPL").await {
Ok(data) => println!("Symbol: {}, Price: {}", data.symbol, data.price),
Err(e) => eprintln!("Error fetching market data: {}", e),
}
}

Gestor de pedidos

El Gestor de pedidos gestiona la creación, envío y seguimiento de cada una de las órdenes. Interactúa con la API de intermediación para ejecutar las operaciones.

use reqwest::Client;
use serde::Serialize;

#[derive(Serialize)]
struct Order {
symbol: String,
qty: u32,
side: String,
order_type: String,
time_in_force: String,
}

async fn place_order(client: &Client, api_key: &str, order: &Order) -> Result<(), reqwest::Error> {
let url = format!("https://api.broker.com/v1/orders?api_key={}", api_key);
let resp = client.post(&url).json(&order).send().await?;
if resp.status().is_success() {
println!("Order placed successfully");
} else {
eprintln!("Error placing order: {:?}", resp.text().await?);
}
Ok(())
}

#[tokio::main]
async fn main() {
let client = Client::new();
let api_key = "your_api_key";
let order = Order {
symbol: "AAPL".to_string(),
qty: 10,
side: "buy".to_string(),
order_type: "market".to_string(),
time_in_force: "gtc".to_string(),
};
match place_order(&client, api_key, &order).await {
Ok(()) => println!("Order executed"),
Err(e) => eprintln!("Error: {}", e),
}
}

Motor de estrategia

El motor de estrategia evalúa las señales de negociación y decide cuándo comprar o vender. He aquí un ejemplo de una estrategia simple de cruce de medias móviles.

fn calculate_sma(prices: &[f64], period: usize) -> Vec<f64> {
prices.windows(period).map(|window| window.iter().sum::<f64>() / period as f64).collect()
}

fn main() {
let prices = vec![100.0, 102.0, 101.0, 105.0, 107.0, 106.0, 108.0, 110.0];
let short_sma = calculate_sma(&prices, 3);
let long_sma = calculate_sma(&prices, 5);

for (short, long) in short_sma.iter().zip(long_sma.iter()) {
if short > long {
println!("Buy signal: short SMA {} > long SMA {}", short, long);
} else {
println!("Sell signal: short SMA {} <= long SMA {}", short, long);
}
}
}

Aplicación de estrategias de negociación avanzadas

Estrategia de reversión a la media

La reversión a la media es una estrategia basada en la idea de que los precios de los activos tienden a volver a su media histórica a lo largo del tiempo. A continuación te mostramos cómo puede implementar una estrategia simple de reversión a la media en NextTrade:

fn calculate_mean(prices: &[f64]) -> f64 {
prices.iter().sum::<f64>() / prices.len() as f64
}

fn mean_reversion_strategy(prices: &[f64], threshold: f64) -> Option<&'static str> {
let mean = calculate_mean(prices);
let current_price = *prices.last().unwrap();

if current_price > mean + threshold {
Some("sell")
} else if current_price < mean - threshold {
Some("buy")
} else {
None
}
}

fn main() {
let prices = vec![100.0, 102.0, 101.0, 105.0, 107.0, 106.0, 108.0, 110.0];
let threshold = 2.0;

match mean_reversion_strategy(&prices, threshold) {
Some("buy") => println!("Buy signal: current price is below mean by threshold"),
Some("sell") => println!("Sell signal: current price is above mean by threshold"),
None => println!("No trade signal"),
_ => unreachable!(),
}
}

Integración del machine learning

La integración de modelos de machine learning en tus estrategias de negociación puede proporcionar capacidad de predicción y adaptabilidad. He aquí un ejemplo simplificado que utiliza un clasificador de árbol de decisión de la caja de máquinas oxidadas:

use rusty_machine::learning::decision_tree::DecisionTree;
use rusty_machine::learning::SupModel;
use rusty_machine::linalg::Matrix;

fn train_model() -> DecisionTree {
let data = Matrix::new(4, 2, vec![1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0]);
let targets = Matrix::new(4, 1, vec![1.0, 0.0, 1.0, 0.0]);

let mut model = DecisionTree::new();
model.train(&data, &targets).unwrap();
model
}

fn predict(model: &DecisionTree, data: Matrix<f64>) -> f64 {
model.predict(&data).unwrap()[0]
}

fn main() {
let model = train_model();
let data = Matrix::new(1, 2, vec![1.0, 1.0]);
let prediction = predict(&model, data);

if prediction == 1.0 {
println!("Buy signal based on model prediction");
} else {
println!("Sell signal based on model prediction");
}
}

Procesamiento de datos en tiempo real

Para seguir siendo competitivo en el ámbito del comercio, es esencial procesar los datos en tiempo real de forma eficiente. Las capacidades asíncronas de Rust combinadas con tokio pueden ayudarte a conseguirlo.

use tokio::time::{self, Duration};
use std::collections::VecDeque;

async fn process_market_data() {
let mut interval = time::interval(Duration::from_secs(1));
let mut prices: VecDeque<f64> = VecDeque::new();

loop {
interval.tick().await;
let price = fetch_latest_price().await;
prices.push_back(price);
if prices.len() > 100 {
prices.pop_front();
}
println!("Latest price: {}", price);
}
}

async fn fetch_latest_price() -> f64 {
// Simulate fetching latest price
105.0
}

#[tokio::main]
async fn main() {
process_market_data().await;
}

Marco de backtesting

Un marco de backtesting robusto es crucial para evaluar el rendimiento de sus estrategias de trading. El módulo de backtesting de NextTrade te permite contrastar tus estrategias con datos históricos.

use chrono::prelude::*;
use std::fs::File;
use std::io::{BufRead, BufReader};

fn load_historical_data(file_path: &str) -> Vec<(DateTime<Utc>, f64)> {
let file = File::open(file_path).unwrap();
let reader = BufReader::new(file);

reader.lines().map(|line| {
let line = line.unwrap();
let parts: Vec<&str> = line.split(',').collect();
let date = Utc.datetime_from_str(parts[0], "%Y-%m-%d %H:%M:%S").unwrap();
let price: f64 = parts[1].parse().unwrap();
(date, price)
}).collect()
}

fn backtest_strategy(prices: &[(DateTime<Utc>, f64)]) {
for (date, price) in prices {
println!("Date: {}, Price: {}", date, price);
// Implement your strategy logic here
}
}

fn main() {
let historical_data = load_historical_data("historical_data.csv");
backtest_strategy(&historical_data);
}

Bot de negociación automatizado

Desplegar un bot de trading automatizado implica configurar un sistema que pueda funcionar continuamente y ejecutar operaciones basadas en las señales de tu estrategia.

use tokio::task;

async fn trading_bot() {
loop {
let market_data = fetch_market_data().await;
let signal = generate_trading_signal(&market_data);

if let Some(order) = signal_to_order(signal) {
place_order(order).await;
}

tokio::time::sleep(Duration::from_secs(60)).await;
}
}

#[tokio::main]
async fn main() {
let bot = trading_bot();
task::spawn(bot).await.unwrap();
}

Buenas prácticas para la implantación en producción

  • Pruebas y simulación: Realiza siempre pruebas retrospectivas de tus estrategias con datos históricos y simúlalas en un entorno de negociación en papel antes de desplegarlas con dinero real.
  • Gestión de errores: Implementa una gestión de errores robusta para gestionar errores de API, problemas de red y otras condiciones inesperadas.
  • Gestión de la concurrencia: Utiliza las características de concurrencia de Rust para manejar múltiples tareas de manera eficiente sin carreras de datos o bloqueos.
  • Monitorización y alertas: Implementa la monitorización para realizar un seguimiento del rendimiento y la salud de tu bot, y configura alertas para cualquier anomalía.
  • Medidas de seguridad: Utiliza métodos seguros para gestionar las claves API y la información confidencial, y asegúrate de que tu sistema es robusto frente a ataques y fallos.
  • Escalabilidad: Diseña tu sistema para manejar cargas crecientes, con la capacidad de escalar a medida que crece tu volumen de operaciones.

Conclusión

NextTrade, con su sólida arquitectura y la utilización de Rust, establece un nuevo estándar para las plataformas de negociación algorítmica. Al aprovechar sus funciones avanzadas y seguir las mejores prácticas, los operadores pueden desarrollar, probar y desplegar sofisticadas estrategias de negociación con confianza. A medida que la tecnología siga evolucionando, plataformas como NextTrade desempeñarán un papel fundamental en la configuración del futuro de la negociación algorítmica, ofreciendo a los operadores las herramientas que necesitan para tener éxito en los dinámicos mercados financieros.

Al integrar el machine learning, el procesamiento de datos en tiempo real y un sólido marco de backtesting, NextTrade permite a los operadores mantenerse a la vanguardia. Tanto si es un operador principiante como un profesional experimentado, las estrategias y prácticas descritas en este artículo le ayudarán a aprovechar todo el potencial de NextTrade en sus operaciones.

The post Dominar el trading algorítmico con NextTrade first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/dominar-trading-algoritmico-con-nexttrade/feed/ 0
Crea un scraper de LinkedIn con Selenium y GPT 4o-Mini de OpenAI https://desa.planetachatbot.com/crea-scraper-de-linkedin-con-selenium-y-gpt-4o-mini-de-openai/?utm_source=rss&utm_medium=rss&utm_campaign=crea-scraper-de-linkedin-con-selenium-y-gpt-4o-mini-de-openai https://desa.planetachatbot.com/crea-scraper-de-linkedin-con-selenium-y-gpt-4o-mini-de-openai/#respond Wed, 21 Aug 2024 06:00:59 +0000 https://desa.planetachatbot.com/?p=18370 Quería crear un scraper de LinkedIn desde cero. Intenté buscar en varias soluciones disponibles públicamente pero ninguna me funcionó. Me di cuenta de que cualquier solución tradicional que funcionara obteniendo elementos de la página web y extrayendo datos relevantes era muy propensa a fallar si cambiaba algún código. Así que decidí lanzar GPT en la […]

The post Crea un scraper de LinkedIn con Selenium y GPT 4o-Mini de OpenAI first appeared on Planeta Chatbot.

]]>
Quería crear un scraper de LinkedIn desde cero. Intenté buscar en varias soluciones disponibles públicamente pero ninguna me funcionó. Me di cuenta de que cualquier solución tradicional que funcionara obteniendo elementos de la página web y extrayendo datos relevantes era muy propensa a fallar si cambiaba algún código. Así que decidí lanzar GPT en la mezcla. Me di cuenta de que no necesitaría hacer toda esa extracción minuciosa de elementos si pudiera obtener «todo» el texto de la página y pedirle al LLM que extrajera la información por mí. Al fin y al cabo, la inferencia es una de sus aplicaciones más potentes. Así que después de adquirir conocimientos básicos sobre Selenium y estudiar algunas soluciones existentes, construí una propia. Vamos a sumergirnos en ella a continuación.

actions.py

import getpass
from . import constants as c
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

def login(driver, email=None, password=None, cookie = None, timeout=30):
try:
driver.get("https://www.linkedin.com/login")
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located(("id", "username")))

email_elem = driver.find_element("id","username")
email_elem.send_keys(email)

password_elem = driver.find_element("id","password")
password_elem.send_keys(password)
password_elem.submit()

element = WebDriverWait(driver, timeout).until(EC.presence_of_element_located(("class name", "global-nav__content"))

except Exception as e:
print(f"Failed to log in: {e}")

Utilizamos la función driver.get() para obtener la página web de inicio de sesión de LinkedIn. Usamos la función WebDriverWait() para buscar un elemento específico en la página web. Utilizamos esta función para esperar a que la página web se cargue completamente. Una vez cargada la página, utilizamos driver.find_element() para obtener el id de nombre de usuario y el id de contraseña. Una vez que obtenemos esos elementos usamos la función send_keys() para colocar nuestros valores en la caja de texto. Para el elemento password, usamos la función submit() para iniciar sesión. A continuación, utilizamos WebDriverWait() de nuevo, esta vez comprobando la existencia de la barra de navegación global que se ve en la parte superior. Si obtenemos eso, significa que estamos dentro.

entity.py

import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
from .objects import Experience, Education, Scraper, Interest, Accomplishment, Contact
import os
from linkedin_scraper import selectors

class Entity(Scraper):

__TOP_CARD = "top-card-background-hero-image"
__WAIT_FOR_ELEMENT_TIMEOUT = 5

def __init__(
self,
linkedin_url=None,
driver=None,
get=True,
close_on_complete=True,
):
self.driver = driver

Creamos una clase llamada Entidad y tenemos dos constantes en ella que se utilizarán más adelante. El constructor inicializa con un linkedin_url, driver, get y close_on_complete. A continuación, establecemos el controlador de acuerdo con lo que se pasó cuando se llamó al constructor.

def scrape(self, close_on_complete=True):    
driver = self.driver

try:
# Wait for the page to load
WebDriverWait(driver, self.__WAIT_FOR_ELEMENT_TIMEOUT).until(
EC.presence_of_element_located(
(
"tag name", "body"
)
)
)
self.focus()
self.wait(5)

# Scroll to the bottom of the page to load all dynamic content
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
self.wait(3) # wait for additional content to load

# Get all the text on the page
page_text = driver.find_element("tag name", "body").text

print("Scraped Text:")
print(page_text)

return page_text

except Exception as e:
print(f"Failed to scrape the page: {e}")
page_text = ""

finally:
if close_on_complete:
driver.quit()

return page_text

La función scrape() va a comprobar la existencia del cuerpo en la página. A continuación, utilizarás la función driver.execute_script() para desplazarte hasta el final de la página y cargarlo todo. Después de eso, extraerás todo el texto de la página web utilizando driver.find_element(«tag name», «body»).text y luego imprimiremos y devolveremos el texto raspado.

linkedin_scraper.py

from linkedin_scraper import Person, actions
from openai import OpenAI
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def scrape_linkedin(linkedin_url, email, password):
# Set up Chrome options
chrome_options = Options()
chrome_options.add_argument("--headless") # Run in headless mode
chrome_options.add_argument("--disable-gpu") # Disable GPU acceleration
chrome_options.add_argument("--no-sandbox") # Bypass OS security model
chrome_options.add_argument("--disable-dev-shm-usage") # Overcome limited resource problems
chrome_options.add_argument("start-maximized") # Start maximized
chrome_options.add_argument("enable-automation") # Enable automation controls
chrome_options.add_argument("--disable-infobars") # Disable infobars
chrome_options.add_argument("--disable-extensions") # Disable extensions
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36")

# Initialize the Chrome driver with the options
service = Service('/usr/bin/chromedriver') # Update with the correct path to your chromedriver
driver = webdriver.Chrome(service=service, options=chrome_options)
client = OpenAI(api_key="OPENAI_API_KEY")
if email and password:
try:

# Log in to LinkedIn
actions.login(driver, email, password)

# Wait for the LinkedIn homepage to load or for login to complete
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".global-nav__me-photo"))
)

# Navigate to the profile page
driver.get(linkedin_url)

# Wait for the profile page to load
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".pv-top-card__photo-wrapper.ml0"))
)

# Create an Entity object for the LinkedIn profile
entity = Entity(linkedin_url=linkedin_url, driver=driver, scrape=False)

# Scrape the LinkedIn profile data
linkedin_data = entity.scrape(close_on_complete=True) # Close browser after scraping

prompt = """Extract and summarize the LinkedIn profile data into the following format:
linkedin_data = {
"name": person.name,
"linkedin_url": person.linkedin_url,
"about": person.about,
"experiences": [str(exp) for exp in person.experiences],
"educations": [str(edu) for edu in person.educations],
"interests": [str(interest) for interest in person.interests],
"accomplishments": [str(accomplishment) for accomplishment in person.accomplishments],
"company": person.company,
"job_title": person.job_title
}

"""

response = client.chat.completions.create(
model="gpt-4o-mini",
temperature=0.1,
messages=[
{"role": "system", "content": f'{prompt}'},
{"role": "user", "content": f'parse the following data: {linkedin_data}'}
]
)

print(response.choices[0].message.content)
return response.choices[0].message.content

except Exception as e:
print(f"Failed to scrape {linkedin_url}: {e}")
linkedin_data = {}

finally:
driver.quit()
else:
return {}

En nuestra función principal scrape_linkedin() primero estamos creando algunas configuraciones necesarias. Estos son chrome_options, services, driver y el cliente OpenAI. A continuación, ejecutamos la función login() con el controlador, el correo electrónico y la contraseña. A continuación, utilizamos el WebDriverWait() para comprobar si estamos en la página de inicio. Comprobamos la foto de perfil en la barra de navegación. Luego usamos la función driver.get() para ir al perfil que queremos scrapear.

Una vez que estemos en esa página, comprobaremos la foto de perfil utilizando WebDriverWait() de nuevo. Si la obtenemos, pasaremos a inicializar nuestro objeto Entidad y luego ejecutaremos la función scrape() para obtener todo el texto de la página web. Una vez que tenemos esos datos, podemos enviarlos a OpenAI utilizando la API de Chat Completions y hacer que extraiga los datos necesarios de ese gran trozo de texto. A continuación, podemos imprimir y devolver los datos.

Toda esta solución se inspiró en el siguiente repositorio de Github: Échale un vistazo.

The post Crea un scraper de LinkedIn con Selenium y GPT 4o-Mini de OpenAI first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/crea-scraper-de-linkedin-con-selenium-y-gpt-4o-mini-de-openai/feed/ 0
Ingeniería Prompt para la flexibilidad cognitiva – LLM https://desa.planetachatbot.com/ingenieria-prompt-para-flexibilidad-cognitiva-llm/?utm_source=rss&utm_medium=rss&utm_campaign=ingenieria-prompt-para-flexibilidad-cognitiva-llm https://desa.planetachatbot.com/ingenieria-prompt-para-flexibilidad-cognitiva-llm/#respond Tue, 20 Aug 2024 06:00:09 +0000 https://desa.planetachatbot.com/?p=18357 Introducción El desarrollo de agentes de inteligencia artificial que puedan, entre otras cosas, pensar, planificar y decidir con una destreza similar a la humana es un área destacada de investigación y debate en la actualidad. Por el momento, los LLM han tomado la delantera como base fundamental de estos agentes. Al perseguir capacidades cada vez […]

The post Ingeniería Prompt para la flexibilidad cognitiva – LLM first appeared on Planeta Chatbot.

]]>
Introducción

El desarrollo de agentes de inteligencia artificial que puedan, entre otras cosas, pensar, planificar y decidir con una destreza similar a la humana es un área destacada de investigación y debate en la actualidad. Por el momento, los LLM han tomado la delantera como base fundamental de estos agentes. Al perseguir capacidades cada vez más complejas, independientemente de los LLM que se utilicen, inevitablemente nos encontramos con los mismos tipos de preguntas una y otra vez, entre ellas:

  1. ¿Dispone el modelo de los conocimientos necesarios para realizar una tarea con precisión y eficacia?
  2. Si dispone de los conocimientos adecuados, ¿cómo podemos activarlos de forma fiable?
  3. ¿Es capaz el modelo de imitar comportamientos cognitivos complejos como el razonamiento, la planificación y la toma de decisiones con un nivel de competencia aceptable?

Este artículo explora estas cuestiones a través de un miniexperimento que he llevado a cabo recientemente y que aprovecha el último benchmark MMLU-Pro. Los hallazgos conducen a algunas ideas interesantes sobre la flexibilidad cognitiva y cómo podríamos aplicar este concepto de la ciencia cognitiva a nuestro agente de IA y a nuestros esfuerzos de ingeniería prompt.

Blackgroud

MMLU-Pro: un desafío de elección múltiple

El recientemente publicado benchmark MMLU-Pro (Massive Multitask Language Understanding) pone a prueba los límites de capacidad de los modelos de IA presentando un conjunto de tareas más robusto y desafiante en comparación con su predecesor, MMLU [1]. El objetivo era crear una evaluación exhaustiva que cubriera una amplia gama de temas, exigiendo a los modelos que poseyeran una amplia base de conocimientos y demostraran la capacidad de aplicarlos en contextos variados. Para ello, MMLU-Pro pone a prueba los modelos con preguntas tipo test muy complejas, orientadas al razonamiento y repartidas en 14 dominios de conocimiento diferentes.

Todos estamos familiarizados con los exámenes tipo test por nuestra propia trayectoria académica. Las estrategias que utilizamos en este tipo de pruebas suelen consistir en una combinación de razonamiento, resolución de problemas, memoria, eliminación, inferencia y conjetura. Nuestra capacidad para alternar sin problemas entre estas estrategias se basa en la flexibilidad cognitiva, que empleamos para adaptar nuestro enfoque a las exigencias de cada pregunta concreta.

La flexibilidad cognitiva abarca capacidades mentales como cambiar de un concepto a otro y pensar en varios conceptos a la vez. Nos permite adaptar nuestro pensamiento a cada situación. ¿Es este concepto potencialmente útil para nuestro agente de IA y para nuestros esfuerzos de ingeniería? Antes de analizarlo, examinemos un ejemplo de pregunta de MMLU-Pro en la categoría «negocios»:

Pregunta 205: Si los beneficios anuales por acción tienen una media de 8,6 $ y una desviación típica de 3,4 $, ¿cuál es la probabilidad de que un BPA observado sea inferior a 5,5 $?

Respuestas: A: 0,3571, B: 0,0625, C: 0,2345, D: 0,5000, E: 0,4112, F: 0,1814, G: 0,3035, H: 0,0923, I: 0.2756, J: 0.1587

Aunque categóricamente etiquetada como «negocios», esta pregunta requiere conocimientos de estadística. Tenemos que normalizar el valor y calcular cuántas desviaciones estándar se aleja de la media para obtener una estimación de la probabilidad. Esto se hace calculando la puntuación Z de la siguiente manera:

Dónde:

X es el valor en cuestión (5,50 $ en este caso).
μ es la media (dada como 8,6 $).
σ es la desviación típica (dada como 3,4 $).

Si sustituimos esos valores en la fórmula obtenemos -0,09118. A continuación, consultamos la tabla de distribución normal estándar y descubrimos que la probabilidad de que Z sea inferior a -0,9118 es de aproximadamente el 18,14%, que corresponde a la respuesta «F» de nuestras opciones.

Creo que se puede afirmar con seguridad que se trata de un problema no trivial que debe resolver un LLM. La respuesta correcta no se puede memorizar y hay que calcularla. ¿Tendría un LLM los conocimientos y la flexibilidad cognitiva necesarios para resolver este tipo de problema? ¿Qué estrategias de ingeniería prompt podríamos emplear?

Ingeniería prompt al rescate

Al abordar el problema anterior con un LLM, podríamos plantearnos: ¿tiene nuestro modelo elegido los conocimientos de estadística necesarios? Suponiendo que los tenga, ¿cómo podemos activar de forma fiable los conocimientos sobre distribuciones normales estándar? Y, por último, ¿puede el modelo imitar los pasos del razonamiento matemático para llegar a la respuesta correcta?

La conocida estrategia de ingeniería de prompts de la «cadena de pensamiento» (CoT) parece encajar a la perfección. Esta estrategia se basa en incitar al modelo a generar pasos de razonamiento intermedios antes de llegar a la respuesta final. Existen dos enfoques básicos.

  • Cadena de pensamiento (CoT): Consiste en dar unos cuantos ejemplos del proceso de razonamiento para guiar el modelo [2].
  • Cadena de Pensamiento Cero (CoT Cero): Consiste en pedir al modelo que genere pasos de razonamiento sin ejemplos previos, a menudo utilizando frases como «Pensemos paso a paso» [3].

Existen muchas otras estrategias, que generalmente se basan en una combinación de activación de características previa a la generación, es decir, centrada en la activación de conocimientos en la solicitud inicial, y activación de características intrageneración, es decir, centrada en la activación dinámica de conocimientos por parte del LLM a medida que genera su salida token a token.

Miniexperimento

Diseño del experimento

Para diseñar el miniexperimento, utilicé ChatGPT-4o y tomé muestras aleatorias de 10 preguntas de cada uno de los 14 dominios de conocimiento del conjunto de datos MMLU-Pro. El experimento pretendía evaluar dos aspectos principales:

  1. Eficacia de las distintas técnicas de ingeniería de prompt: Específicamente, el impacto del uso de diferentes técnicas para activar el conocimiento necesario y el comportamiento deseado en el modelo. Las técnicas se seleccionaron para que se ajustaran a distintos grados de flexibilidad cognitiva y todas se basaron en el disparo cero.
  2. El impacto de limitar deliberadamente el razonamiento y la flexibilidad cognitiva: En concreto, cómo afecta a la precisión el hecho de limitar la capacidad del modelo para razonar abiertamente (y, en consecuencia, limitar gravemente la flexibilidad cognitiva).

Las diferentes técnicas de pregunta probadas se basaban en las siguientes plantillas:

  • Pregunta directa – {Pregunta}. Seleccione la respuesta correcta entre las siguientes opciones:{Respuestas}. Responda con la letra y la respuesta seleccionadas.
  • TdC – {Pregunta}. Pensemos paso a paso y seleccionemos la respuesta correcta de entre las siguientes opciones de respuesta: {Respuestas}. Responda con la letra y la respuesta seleccionadas.
  • Activación del Dominio del Conocimiento – {Pregunta}. Pensemos en los conocimientos y conceptos necesarios y seleccionemos la respuesta correcta de entre las siguientes opciones de respuesta:
  • {Respuestas}. Responda con la letra y la respuesta seleccionadas.
  • Andamios contextuales – {Pregunta}. Mis expectativas son que responda correctamente a la pregunta. Crea un contexto operativo para ti mismo que maximice el cumplimiento de mis expectativas y selecciona la respuesta correcta de entre las siguientes opciones de respuesta: {Respuestas}. Responda con la letra y la respuesta seleccionadas. [4]

El enfoque de Pregunta Directa sirvió como línea de base, permitiendo probablemente el mayor grado de flexibilidad cognitiva del modelo. Es probable que CoT genere la menor flexibilidad cognitiva, ya que el modelo debe proceder paso a paso. La Activación del Dominio del Conocimiento y los Andamios Contextuales se sitúan entre la Pregunta Directa y el CoT.

El razonamiento deliberadamente restrictivo se consiguió tomando la última línea de las plantillas de preguntas anteriores, es decir, «Responde con la letra y la respuesta seleccionadas» y especificando en su lugar «Responde sólo con la letra y la respuesta seleccionadas y nada más».

Si te interesa el código que utilicé para realizar el experimento y los resultados, puedes encontrarlos en este repositorio de GitHub enlazado aquí.

Resultados

A continuación se presentan los resultados de las distintas técnicas de pronóstico y sus variantes con restricciones de razonamiento:

Todas las preguntas de razonamiento sin restricciones obtuvieron resultados comparables, aunque el enfoque de pregunta directa fue ligeramente mejor que los demás. Esto fue una sorpresa, ya que el artículo de MMLU-Pro [1] señala un rendimiento significativamente inferior en la pregunta directa y un fuerte aumento del rendimiento con CoT de pocos disparos. No me detendré aquí en la discrepancia, ya que el propósito del miniexperimento no era replicar su configuración.

Lo más importante para este miniexperimento es que, cuando se restringió deliberadamente el razonamiento, todas las técnicas mostraron un descenso comparable en la precisión, pasando de una media del 66% al 51%. Este resultado coincide con lo que esperábamos. La observación más pertinente es que ninguna de las técnicas consiguió mejorar la activación del conocimiento previo a la generación más allá de lo que ocurriría con la pregunta directa, en la que la activación de características previas a la generación se produce principalmente al exponer el modelo al texto de las opciones de pregunta y respuesta.

La conclusión general de estos resultados de alto nivel sugiere que una combinación óptima para una pronta eficacia de la ingeniería puede muy bien implicar:

  1. Permitir que el modelo ejerza cierto grado de flexibilidad cognitiva, como se ejemplifica mejor en el enfoque de Pregunta Directa.
  2. Permitir que el modelo razone abiertamente, de forma que las trazas de razonamiento formen parte activa de la generación.

La dimensión del coste computacional

Aunque no se discute a menudo, la eficiencia de los tokens es cada vez más importante a medida que los LLM se abren camino en diversos casos de uso de la industria. El siguiente gráfico muestra la precisión de cada técnica de consulta sin restricciones frente a la media de tokens generados en la respuesta.

Aunque el diferencial de precisión no es el objetivo principal, la eficiencia del enfoque de Pregunta Directa, que genera una media de 180 tokens por respuesta, es notable en comparación con CoT, que produjo aproximadamente 339 tokens por respuesta (es decir, un 88% más). Dado que la precisión es comparable, cabe suponer que CoT es, por término medio, menos eficaz que las demás estrategias en lo que se refiere a la activación del conocimiento intrageneracional, lo que produce resultados excesivamente verborreicos. Pero, ¿a qué se debe este exceso de verbosidad? Para intentar responder a esta pregunta, resultó útil examinar las preguntas de razonamiento sin restricciones y el número de veces que el modelo optó por responder sólo con la respuesta y sin ningún rastro de razonamiento, aunque no se le hubiera indicado explícitamente que lo hiciera. Los resultados fueron los siguientes

LLM

Lo que resultó aún más interesante fue la precisión cuando el modelo optó por responder directamente sin ningún rastro de razonamiento, lo que se muestra en la tabla siguiente:

La precisión osciló entre el 64% y el 70% sin que se generara ningún rastro de razonamiento. Incluso con las preguntas de MMLU-Pro, diseñadas a propósito para requerir razonamiento y resolución de problemas, el modelo parece demostrar algo parecido a la selección de diferentes estrategias en función de la pregunta concreta, cuando no está excesivamente condicionado por la pregunta.

Implicaciones prácticas

Lo que se desprende de estos resultados es que las estrategias sencillas pueden ser tan eficaces como las excesivamente estructuradas. Aunque el objetivo de CoT es simular el razonamiento induciendo activaciones de rasgos específicos orientados al razonamiento, puede que no siempre sea necesario u óptimo, especialmente si la generación excesiva de fichas es un problema. En su lugar, un enfoque potencialmente más adecuado puede ser permitir que el modelo ejerza su flexibilidad cognitiva.

Conclusiones: Preparando el camino para la flexibilidad cognitiva en los agentes de IA

Los resultados de este miniexperimento ofrecen una visión convincente de la importancia de la flexibilidad cognitiva en los LLM y los Agentes de IA. En la cognición humana, la flexibilidad cognitiva se refiere a la capacidad de adaptar el pensamiento y el comportamiento en respuesta a tareas o demandas cambiantes. Implica pasar de un concepto a otro, mantener varios conceptos simultáneamente y cambiar la atención según sea necesario. En el contexto de los LLM, puede entenderse como la capacidad del modelo para ajustar dinámicamente sus activaciones internas en respuesta a estímulos textuales.

Si se sigue prestando atención al desarrollo de tecnologías y técnicas en este ámbito, se podría mejorar significativamente la capacidad de los agentes de IA en una serie de tareas complejas. Por ejemplo, la exploración de esta idea junto con otras ideas como las expuestas por Anthropic en su reciente artículo «Scaling Monosemanticity: Extracting Interpretable Features from Claude 3 Sonnet», podría dar lugar a técnicas que desbloqueen la capacidad de observar y adaptar dinámicamente el nivel de flexibilidad cognitiva empleado en función de la complejidad y el dominio de la tarea.

A medida que ampliemos los límites de la IA, la flexibilidad cognitiva será probablemente clave para crear modelos que no sólo funcionen con fiabilidad, sino que también comprendan y se adapten a las complejidades del mundo real.

Gracias por leerme y sígueme para conocer los resultados de futuras exploraciones relacionadas con este trabajo. Si quieres hablar de ello, no dudes en ponerte en contacto conmigo en LinkedIn.
Salvo que se indique lo contrario, todas las imágenes de este artículo son del autor.

The post Ingeniería Prompt para la flexibilidad cognitiva – LLM first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/ingenieria-prompt-para-flexibilidad-cognitiva-llm/feed/ 0
Programación con IA – Llamando a APIs https://desa.planetachatbot.com/programacion-con-ia-apis/?utm_source=rss&utm_medium=rss&utm_campaign=programacion-con-ia-apis https://desa.planetachatbot.com/programacion-con-ia-apis/#respond Tue, 13 Aug 2024 06:00:18 +0000 https://desa.planetachatbot.com/?p=18319 Hace unas semanas me pidieron que impartiera una breve clase sobre programación con IA. Me adelanté a preparar obedientemente las diapositivas y el código, pero de alguna manera los materiales crecieron y crecieron. Así que pensé ¿por qué no reunir todo ese material, y más, en una serie de artículos con él? Estoy seguro de […]

The post Programación con IA – Llamando a APIs first appeared on Planeta Chatbot.

]]>
Hace unas semanas me pidieron que impartiera una breve clase sobre programación con IA. Me adelanté a preparar obedientemente las diapositivas y el código, pero de alguna manera los materiales crecieron y crecieron. Así que pensé ¿por qué no reunir todo ese material, y más, en una serie de artículos con él? Estoy seguro de que habrá otros más allá de la clase que puedan beneficiarse de ello.

También pueden convertirse en materiales de referencia para la clase después de la sesión.
Así que aquí está la primera parte de la clase (1 de 4), que es todo acerca de llamar a las API de AI proveedor a través de las API REST y bibliotecas.

  • Descargo de responsabilidad: esto se supone que es material introductorio por lo que hay un montón de cosas que he dejado fuera. Esto no es ni pretende ser exhaustivo.

Empecemos con un calentamiento. Con esto me refiero a llamar a algunas APIs. Llamar a APIs para hacer IA es la forma más común y sencilla de acceder a las capacidades de la IA. Mucha gente desprecia esto y lo considera «no lo suficientemente IA». Pero eso es una tontería: el valor del sistema es ofrecer capacidades a los usuarios, no cuánta IA se utiliza.

Actualmente existen muchos proveedores con API, como OpenAI (GPT), Google (Gemini), Anthropic (Claude), Mistral (Mistral), Cohere (Command), etc. Además de estos hay proveedores de plataformas que proporcionan varias capacidades como Replicate, Anyscale, Modal, Banana, etc.
En este artículo, vamos a empezar simplemente con la llamada a las REST API.

REST API

Que yo sepa, todos los proveedores tienen una REST API. Llamarlos es muy simple, sólo tenemos que utilizar curl con un punto final de la URL de la API, y pasarle la clave de la API, y la carga JSON.

Aquí hay un ejemplo de llamada a la API de OpenAI para completar chats.

$ curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Why is the sky blue?"
}
]
}'

Necesitas una clave API válida, que puede obtener de cada proveedor. La mayoría de las veces basta con registrarse para obtener una cuenta y crear una clave de API. Una vez que tengas la clave API, puedes introducirla directamente o establecerla como variable de entorno:

$ export OPENAI_API_KEY=<your API key>

Cuando llames a la API, deberías devolver algo como esto:

{
"id": "chatcmpl-9RWBzicE7v7A1ZRLWUMX3a6zwooWd",
"object": "chat.completion",
"created": 1716345631,
"model": "gpt-4o-2024-05-13",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The sky appears blue due to a phenomenon called Rayleigh scattering. Here’s a more detailed explanation:\n\n1. **Sunlight Composition**: Sunlight, or white light, is composed of a spectrum of colors, each with different wavelengths. The visible spectrum ranges from shorter wavelengths (blue and violet) to longer wavelengths (red and orange).\n\n2. **Interaction with the Atmosphere**: When sunlight enters Earth's atmosphere, it encounters molecules and small particles. The shorter wavelengths of light (blue and violet) are scattered more effectively by these particles than the longer wavelengths (red, orange, and yellow). \n\n3. **Human Perception**: While violet light is scattered even more than blue light, our eyes are more sensitive to blue light and there is less violet light in sunlight to begin with. Moreover, some of the violet light is absorbed by the upper atmosphere. As a result, we see the sky as blue.\n\n4. **Resulting Blue Sky**: The scattered blue light is what predominantly reaches our eyes from various directions, making the sky look blue when viewed from the ground during the day.\n\nThis scattering effect is more pronounced when the sun is lower in the sky, which is why we see reddish colors at sunrise and sunset. In these cases, the light has to pass through more of the atmosphere, scattering out even more blue and green light, and leaving the reds and oranges to dominate the sky's appearance."
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 23,
"completion_tokens": 286,
"total_tokens": 309
},
"system_fingerprint": "fp_729ea513f7"
}

Tal vez OpenAI fue el primero que ideó este tipo de API, o tal vez porque es el más popular, muchos otros proveedores utilizan también un formato similar en sus REST API. Por ejemplo, esta es la de Anthropic.

$ curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-3-opus-20240229",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Why is the sky blue?"}
]
}'

Como puedes ver, la clave API se pasa a través de una cabecera diferente pero la carga útil es casi exactamente la misma aunque hay ligeras diferencias debido a cómo funciona el modelo. Por ejemplo, no puedes pasar el contenido del rol del sistema como parte de los mensajes en Anthropic.

Este es otro ejemplo, de Mistral.

$ curl https://api.mistral.ai/v1/chat/completions \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header "Authorization: Bearer $MISTRAL_API_KEY" \
--data '{
"model": "mistral-large-latest",
"messages": [
{
"role": "user",
"content": "Why is the sky blue?"
}
]
}'

Dicho esto, Google utiliza un enfoque ligeramente diferente de la API, y pasa la clave de la API como parte de la consulta de la URL, y el modelo está incrustado como parte de la URL. La carga útil también es diferente, pero la idea es prácticamente la misma.

$ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=$API_KEY" \
-H 'Content-Type: application/json' \
-d '{ "contents":[
{ "parts":[{"text": "Why is the sky blue?"}]}
]
}'

Las REST API son realmente útiles y prácticamente universales. Si estás programando en un lenguaje que no está soportado directamente por el proveedor, puedes utilizar una librería cliente HTTP y llamar directamente a la API REST. Todos los lenguajes de programación razonables tienen una biblioteca cliente HTTP, ya sea en sus bibliotecas estándar o en las de terceros, así que ya está.

Sin embargo, la mayoría de los proveedores también ofrecen soporte para Python como mínimo, principalmente porque la mayoría de las cosas de IA se programan con Python.

Python

Por ejemplo, así es como se puede llamar a OpenAI utilizando su biblioteca Python.

from openai import OpenAI
client = OpenAI()

completion = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Why is the sky blue?"}
]
)

print(completion.choices[0].message.content)

Es así de sencillo. Puedes configurar parámetros y opciones al crear el cliente, pero eso es todo. Habrás notado que ya no necesitamos especificar la clave de la API. Eso es porque si has configurado la clave de la API como una variable de entorno, la biblioteca Python la recogerá allí.

Lo mismo ocurre con Anthropic.

import anthropic

message = anthropic.Anthropic().messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
messages=[
{"role": "user", "content": "Why is the sky blue?"}
]
)

print(message.content)

Además de con Mistral.

from mistralai.client import MistralClient
from mistralai.models.chat_completion import ChatMessage

client = MistralClient()

chat_response = client.chat(
model="mistral-large-latest",
messages=[
ChatMessage(role="user", content="Why is the sky blue?")
],
)

print(chat_response.choices[0].message.content)

La biblioteca Python de Google también es muy fácil de usar, aunque es ligeramente diferente del resto.

import google.generativeai as genai

model = genai.GenerativeModel('gemini-1.5-flash-latest')
chat = model.start_chat(history=[])
response = chat.send_message("Why is the sky blue?")

print(response.text)

Como puedes ver, Python está muy bien soportado. El otro lenguaje bien soportado es Javascript.

Javascript

Aunque Python es el lenguaje mejor soportado, debido a su enorme popularidad, Javascript/Typescript también suele serlo. Echemos un vistazo a cómo acceder a las APIs de OpenAI usando Javascript con node.js.

import OpenAI from "openai";

const openai = new OpenAI();

const completion = await openai.chat.completions.create({
model: "gpt-4o",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Why is the sky blue?" }
],
});

console.log(completion.choices[0]);

Como antes en las librerías Python, ya no necesitamos especificar la clave API. Eso es porque si has configurado la clave API como una variable de entorno la librería Javascript la recogerá ahí.

Esta es la salida del resultado JSON (sólo el completion.choices[0]).

{
index: 0,
message: {
role: 'assistant',
content: "The sky appears blue because of a phenomenon called Rayleigh scattering. This scattering occurs when sunlight enters Earth's atmosphere and interacts with the molecules and small particles in the air.\n" +
'\n' +
"Here's a step-by-step breakdown of why the sky looks blue:\n" +
'\n' +
'1. **Sunlight Composition**: Sunlight, or white light, is made up of multiple colors, each with different wavelengths. The colors range from violet and blue (shorter wavelengths) to red and orange (longer wavelengths).\n' +
'\n' +
'2. **Scattering**: As sunlight passes through the atmosphere, it collides with gas molecules and small particles. The shorter wavelengths of light (blue and violet) are scattered in all directions by these molecules and particles much more than the longer wavelengths (red and orange).\n' +
'\n' +
'3. **Human Perception**: Even though violet light is scattered even more than blue light, our eyes are more sensitive to blue light and less sensitive to violet light. Additionally, some of the violet light is absorbed by the upper atmosphere. Therefore, the sky predominantly appears blue to us.\n' +
'\n' +
'4. **Viewing Angle**: When you look up at the sky, you are seeing this scattered blue light coming from all parts of the sky, giving it its characteristic color.\n' +
'\n' +
"In summary, the sky is blue because the shorter blue wavelengths of sunlight are scattered more widely in all directions by the molecules in Earth's atmosphere, and our eyes are better equipped to see blue light."
},
logprobs: null,
finish_reason: 'stop'
}

Del mismo modo, así es como se puede llamar a la API antrópica utilizando Javascript con node.js.

import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic();

const completion = await anthropic.messages.create({
model: "claude-3-haiku-20240307",
max_tokens: 1024,
messages: [
{"role": "user", "content": "Why is the sky blue?"}
]
});

console.log(completion);

No voy a seguir con los otros proveedores, pero más o menos te haces una idea. Si prefieres trabajar con las librerías soportadas oficialmente, Python y Javascript son el camino a seguir. Además de la API REST, Python y Javascript, la mayoría de los proveedores no tienen soporte oficial para otros lenguajes, aunque Google tiene una gama mucho más amplia de lenguajes soportados.

Sin embargo, esto no significa que no haya bibliotecas para otros lenguajes.

Bibliotecas de terceros

Existen multitud de librerías de terceros. Si echas un vistazo a la documentación de OpenAI, verás que hay librerías de terceros para casi todos los lenguajes populares. Por ejemplo, el paquete go-openai permite llamar a las bibliotecas de OpenAI en Go.

package main

import (
"context"
"fmt"
"os"

openai "github.com/sashabaranov/go-openai"
)

func main() {
client := openai.NewClient(os.Getenv("OPENAI_API_KEY"))
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: openai.GPT4o,
Messages: []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleUser,
Content: "Why is the sky blue?",
},
},
},
)

if err != nil {
fmt.Printf("ChatCompletion error: %v\n", err)
return
}

fmt.Println(resp.Choices[0].Message.Content)
}

Aquí tienes una librería OpenAI de terceros para Swift, llamada SwiftOpenAI. Para usarla, añádela como dependencia del paquete en tu proyecto XCode. Este es un ejemplo de una función para llamar a las APIs de OpenAI.

    func sendMessage() async {
let input = userInput.trimmingCharacters(in: .whitespacesAndNewlines)
guard !input.isEmpty else { return }

let message = Message(content: input, isUser: true)
messages.append(message)
userInput = ""

let openAI = SwiftOpenAI(apiKey: Config.openAIKey)
let msgs: [MessageChatGPT] = [
MessageChatGPT(text: "You are a helpful assistant.", role: .system),
MessageChatGPT(text: input, role: .user)
]

let optionalParameters = ChatCompletionsOptionalParameters(
temperature: 0.7,
stream: true,
maxTokens: 1024
)

do {
let stream = try await openAI.createChatCompletionsStream(
model: .gpt4o(.base),
messages: msgs,
optionalParameters: optionalParameters
)

let resp = Message(content: "", isUser: false)
messages.append(resp)

for try await response in stream {
let content = response.choices[0].delta?.content ?? ""
if let lastMessage = messages.last, !lastMessage.isUser {
let updatedContent = lastMessage.content + content
messages[messages.count - 1] = Message(content: updatedContent, isUser: false)
}
}
} catch {
print("Error: \(error)")
if let lastMessage = messages.last, !lastMessage.isUser {
messages[messages.count - 1] = Message(content: "Cannot get response from OpenAI: \(error)", isUser: false)
}
}
}

Todas estas librerías de terceros son buenas pero en su mayoría sólo soportan 1 proveedor. Si quieres acceder a múltiples proveedores normalmente necesitas usar varias librerías a la vez, o también puedes probar frameworks LLM.

LLM Frameworks

Los frameworks de LLM son un tipo de marco de desarrollo que nos permite escribir aplicaciones basadas en LLM. Estos frameworks proveen soporte y estructura, y usualmente una forma determinada de escribir aplicaciones basadas en LLM.

Hay un gran número de frameworks LLM, y algunos de ellos son muy populares, más que las librerías con soporte oficial o de terceros. Esto se debe a que estos frameworks proporcionan a los desarrolladores un montón de capacidades. Nos permiten conectarnos a múltiples proveedores LLM al mismo tiempo, tiene conectores a múltiples fuentes de datos e incluso implementar agentes sobre los LLM básicos.

Hay un gran número de frameworks incluyendo Langchain, LlamaIndex, Haystack, etc. pero en este artículo sólo hablaré de Langchain y LlamaIndex, ya que actualmente son los dos frameworks más populares para construir aplicaciones basadas en LLM.

Langchain 🦜🔗

El framework más popular es probablemente Langchain, que fue publicado por primera vez en octubre de 2022. Ha evolucionado rápidamente desde entonces para cubrir casi todo en el mundo LLM, culminando en cerca de 400 versiones hasta la fecha. En un momento dado, las versiones eran casi diarias, ¡e incluso a veces dos al día!

Durante el último año Langchain ha pasado de ser una librería Python relativamente simple a un ecosistema de capacidades que van desde la librería central a un servidor de despliegue y un conjunto de herramientas de observabilidad.

Aquí está lo básico de cómo utilizar Langchain para conectarse a OpenAI y llamar a su API de chat.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(model_name="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
("user", "{input}")
])
output_parser = StrOutputParser()

chain = prompt | llm | output_parser
results = chain.invoke({"input": "why is the sky blue?"})

print(results)

El código no parece muy diferente a simple vista, pero te habrás dado cuenta de que hemos encadenado el prompt del chat, LLM y el parser de salida para producir los resultados. Este es un ejemplo de una de las características más poderosas de Langchain y la que le dio a Langchain su nombre – la cadena.

Una cadena es una secuencia de llamadas enlazadas entre sí. Las cadenas se crean usando el Lenguaje de Expresión Langchain (LCEL) y la cadena más básica es la que se muestra arriba:

chain = prompt | llm | output_parser

Para ejecutar la cadena, simplemente llamamos a uno de los pocos métodos de la cadena (en el caso del código anterior, usamos invoke) con la entrada apropiada, y obtendremos la salida.

IA

Las cadenas son potentes y configurables. Veamos cómo queremos realizar una sencilla generación aumentada de recuperación (RAG) pasando el contexto junto con la pregunta al LLM.

Utilizaremos un documento de texto, en este caso, los procedimientos parlamentarios en Singapur sobre el Comité de Suministros para el Ministerio de Comunicaciones e Información (MCI) en enero de 2024. Saqué el texto del sitio y lo guardé como un archivo de texto llamado hansard.txt.

from langchain_community.vectorstores import DocArrayInMemorySearch
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_openai import OpenAIEmbeddings
from langchain_openai import ChatOpenAI

def extract(file_path):
with open(file_path, 'r') as file:
return [line.strip() for line in file if line.strip()]


model = ChatOpenAI(model="gpt-4o")
vectorstore = DocArrayInMemorySearch.from_texts(
texts=extract('data/hansard.txt'),
embedding=OpenAIEmbeddings(),
)
retriever = vectorstore.as_retriever()
template = """Answer the question based only on the following context:
{context}

Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
output_parser = StrOutputParser()
setup_and_retrieval = RunnableParallel(
{"context": retriever, "question": RunnablePassthrough()}
)
chain = setup_and_retrieval | prompt | model | output_parser

results = chain.invoke("How has Smart Nation improved citizen's lives?")
print(results)

En el código anterior, primero creamos un almacén de vectores en memoria a partir de cada línea del documento hansard.txt, utilizando incrustaciones de OpenAI. A partir del almacén de vectores, creamos un recuperador, que nos permite obtener las líneas apropiadas como entrada para el prompt.

Ahora, dada una entrada del usuario, la pasamos al recuperador para obtener las líneas del almacén de vectores. La misma entrada del usuario también se pasa al prompt. Estos 2 son ejecutados al mismo tiempo por RunnableParallel, y la salida es enviada al prompt como la pregunta y el contexto.

El resto es más o menos lo mismo, pero aquí está la salida.

% python langchain_test_rag.py
The Smart Nation initiative has improved citizens' lives in Singapore by increasing satisfaction with government services, which rose from 73% to 83% between 2014 and 2023. Additionally, 84% of Singaporeans feel that digital technologies have made their lives easier. The initiative aims to enhance everyday convenience and quality of life, empower people to live more meaningful and fulfilled lives, and ensure that no one is left behind.

Como puedes ver, las cadenas son un mecanismo muy potente. Este mecanismo de encadenamiento no es exclusivo de Langchain. El framework Haystack, que también es un framework LLM bastante popular por sí mismo, lo llama pipeline, mientras que otros frameworks como LLMFlows lo llaman flow.

LlamaIndex

Otro framework LLM popular es LlamaIndex. LlamaIndex comenzó en noviembre de 2022 como un framework llamado GPTIndex . La premisa de LlamaIndex es conectar LLMs a sus datos. Puedes notar que tanto LlamaIndex como Langchain empezaron más o menos al mismo tiempo. De hecho, ambos creadores de Langchain (Harrison Chase) y LlamaIndex (Jerry Liu) eran compañeros en Robust Intelligence, una empresa de seguridad de IA.

Echemos un vistazo rápido a cómo utilizar LlamaIndex para completar chats.

from llama_index.core import Settings
from llama_index.core.llms import ChatMessage
from llama_index.llms.openai import OpenAI

Settings.llm = OpenAI(model="gpt-4o")
messages = [
ChatMessage(
role="system", content="You are a helpful assistant."
),
ChatMessage(role="user", content="Why is the sky blue?"),
]
resp = OpenAI().chat(messages)
print(resp)

Como se puede ver, esto no es muy diferente de Langchain o cualquier API, pero la ventaja LlamaIndex tiene es su enfoque en la conexión con los datos. Como era de esperar, el código para hacer un RAG sencillo es bastante simple.

from llama_index.core import Settings, VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI

Settings.llm = OpenAI(model="gpt-4o")

documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("How has Smart Nation improved citizen's lives?")
print(response)

En primer lugar, tomamos los archivos del directorio de datos (que no es más que nuestro archivo hansard.txt) y los almacenamos en un almacén vectorial. Después usamos ese almacén vectorial como motor de consulta y le enviamos una consulta, y usará los datos de nuestro documento para formar su respuesta.

Langchain y LlamaIndex son dos potentes frameworks tras el rápido ritmo de evolución. Cada uno de ellos tiene sus propias fortalezas y en este momento, el uso de cualquiera de ellos depende principalmente de la preferencia personal.

Resumen

Esta es la primera parte de la clase que impartiré sobre programación con IA. En el próximo artículo, profundizaré en los LLM locales, es decir, los LLM que puedes implementar en tus propias máquinas, incluso en tu propio portátil.

The post Programación con IA – Llamando a APIs first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/programacion-con-ia-apis/feed/ 0
De la ingeniería prompt a la ingeniería de agentes https://desa.planetachatbot.com/de-ingenieria-prompt-a-ingenieria-de-agentes/?utm_source=rss&utm_medium=rss&utm_campaign=de-ingenieria-prompt-a-ingenieria-de-agentes https://desa.planetachatbot.com/de-ingenieria-prompt-a-ingenieria-de-agentes/#respond Thu, 01 Aug 2024 06:00:06 +0000 https://desa.planetachatbot.com/?p=18195 Introducción Poco más de un año después del lanzamiento de ChatGPT, está claro que la percepción pública de la «IA» ha cambiado radicalmente. En parte se debe a una mayor concienciación general, pero sobre todo a la constatación de que los sistemas basados en IA pueden ser (¿ya lo son?) capaces de alcanzar un nivel […]

The post De la ingeniería prompt a la ingeniería de agentes first appeared on Planeta Chatbot.

]]>
Introducción

Poco más de un año después del lanzamiento de ChatGPT, está claro que la percepción pública de la «IA» ha cambiado radicalmente. En parte se debe a una mayor concienciación general, pero sobre todo a la constatación de que los sistemas basados en IA pueden ser (¿ya lo son?) capaces de alcanzar un nivel de competencia y rendimiento humano. En muchos sentidos, ChatGPT ha servido como prueba de concepto para la IA en su conjunto. El trabajo en esta demostración comenzó hace más de medio siglo y ahora ha aportado pruebas convincentes de que estamos más cerca de una realidad en la que podemos «crear máquinas que realicen funciones que requieren inteligencia cuando las realizan personas», tomando prestada la definición de Ray Kurzweil. No es de extrañar, pues, que los debates y el desarrollo en torno a la ingeniería de agentes de IA se hayan disparado en los últimos meses. Son la encarnación de las aspiraciones a las que siempre ha aspirado la IA.

Para ser claros, el concepto de agentes de IA no es nuevo. C-3PO, de La Guerra de las Galaxias, es la IA encarnada por excelencia, capaz de comprender el lenguaje natural, dialogar y actuar de forma autónoma. En el ámbito académico, el libro de texto de Norvig y Russell sobre IA, Artificial Intelligence: A Modern Approach, de Norvig y Russell, afirma que los agentes inteligentes son el principal tema unificador. Las ideas en torno a los agentes de IA, nacidas en la ciencia o en la ficción, parecen todas un poco más realizables con la llegada de modelos como ChatGPT, Claude y Gemini, ampliamente competentes en diversos dominios del conocimiento y dotados de una gran capacidad de comprensión y de diálogo a nivel humano. Si añadimos nuevas capacidades como la «visión» y la llamada a funciones, el escenario está preparado para la proliferación del desarrollo de agentes de IA.

A medida que avanzamos en el camino hacia el desarrollo de agentes de IA, parece necesario empezar a pasar de la ingeniería de prompts a algo más amplio, como la ingeniería de agentes, y establecer los marcos, metodologías y modelos mentales adecuados para diseñarlos de forma eficaz. En este artículo, me propongo explorar algunas de las ideas y preceptos clave de la ingeniería de agentes en el contexto del LLM.

Exploremos a alto nivel las secciones clave del Marco de Ingeniería de Agentes. Comenzamos con los «Requisitos de las capacidades del agente», en los que pretendemos definir claramente lo que debe hacer el agente y su nivel de competencia. En «Ingeniería y diseño de agentes» evaluamos las tecnologías disponibles y empezamos a pensar en la anatomía y orquestación de nuestros agentes.

Esta articulación inicial del marco pretende ser un modelo mental práctico y es cierto que no es exhaustivo en todos los frentes. Pero creo que es útil empezar por algún sitio y luego perfeccionarlo y mejorarlo con el tiempo.

El marco de ingeniería de agentes

Introducción

¿Cuál es el propósito de construir un agente de IA? ¿Tiene un trabajo o una función? ¿Acciones en apoyo de objetivos? ¿O objetivos en apoyo de acciones? ¿Es mejor un agente con múltiples capacidades que un enjambre de agentes para un trabajo concreto? Lo bueno del lenguaje humano es que es flexible y nos permite ampliar metafóricamente los conceptos en muchas direcciones. El inconveniente de esto es que puede llevar a la ambigüedad. Al articular el marco, intento evitar a propósito las distinciones semánticas entre términos clave, ya que muchos de ellos pueden utilizarse indistintamente. En lugar de ello, nos esforzamos por sacar a la superficie conceptos que se generalicen en su aplicación a la Ingeniería de Agentes de IA en sentido amplio. Como resultado, el marco en esta etapa es más un modelo mental que pretende guiar el proceso de pensamiento en torno a la Ingeniería de Agentes. Las ideas centrales son relativamente sencillas, como se puede ver en el siguiente gráfico:

Ingeniería
  • A los agentes de IA se les asigna(n) Trabajo(s)
  • Los trabajos requieren acciones para completarse
  • Para realizar la(s) acción(es) se requieren Capacidades
  • Las capacidades tienen un nivel de competencia necesario.
  • El nivel de competencia requerido requiere tecnologías y técnicas
  • Las tecnologías y técnicas requieren orquestación+

Requisitos de las capacidades del agente

El trabajo a realizar

El paso inicial en el diseño de un agente de IA es definir claramente lo que el agente debe hacer. ¿Cuáles son los principales trabajos, tareas u objetivos que debe cumplir el agente? Esto puede enmarcarse en un objetivo de alto nivel o desglosarse en tareas específicas. Puede que decida utilizar un enfoque de enjambre multiagente y asignar a cada agente una tarea. El lenguaje y el nivel de detalle pueden variar. Por ejemplo:

  • El trabajo de un bot de chat de comercio electrónico podría consistir en gestionar consultas generales, analizar el comportamiento de los clientes y hacer recomendaciones de productos.
  • El trabajo de un agente de creación de contenidos podría consistir en aportar ideas y redactar artículos o entradas de blog.

Nótese que en ambos casos, etiquetas como trabajos, tareas, objetivos, etc. podrían utilizarse indistintamente en el contexto de lo que se supone que debe hacer el agente.

Las acciones a realizar para llevar a cabo el trabajo

Una vez definidas las tareas a realizar, el siguiente paso es determinar las acciones específicas que el agente debe llevar a cabo en relación con esa tarea. Se pasa de definir simplemente lo que el agente debe conseguir a especificar cómo lo conseguirá mediante acciones concretas. En esta fase también es importante empezar a considerar el nivel adecuado de autonomía del agente. Por ejemplo:

Para un agente de creación de contenidos, las acciones podrían incluir:

  • Llamar a otro agente para obtener información sobre tendencias de contenidos.
  • Generar una lista de ideas de contenidos basada en esas tendencias y en las preferencias del público objetivo.
  • Redactar artículos o entradas de blog.
  • Recibir instrucciones de un usuario humano sobre ediciones y ajustes.

El agente de creación de contenido puede generar y redactar contenido de forma autónoma, con un editor humano brindando la aprobación final. O se puede contratar a un editor agente independiente para realizar una primera revisión antes de que intervenga un editor humano.

Las capacidades necesarias

Ahora que hemos delineado las acciones que nuestros agentes deben tomar para realizar el trabajo, procedemos a articular las capacidades necesarias para permitir esas acciones. Pueden incluir todo, desde diálogo en lenguaje natural, recuperación de información, generación de contenido, análisis de datos, aprendizaje continuo y más. También se pueden expresar en un nivel más técnico, como llamadas API, llamadas a funciones, etc. Por ejemplo, para nuestro agente de creación de contenido, las capacidades deseadas podrían ser:

  • Llamada dinámica de la API del agente de tendencias de contenido.
  • Capacidades de lluvia de ideas y resumen.
  • Tono de generación de contenidos adecuados sobre temas y tendencias actuales.
  • La capacidad de actuar siguiendo instrucciones proporcionadas por humanos para editar contenido.
  • Memoria

En última instancia, es importante centrarse en expresar las capacidades de manera que no limiten las opciones y la eventual selección de con qué tecnologías trabajar. Por ejemplo, aunque todos estamos bastante enamorados de los LLM, los modelos de acción grande (LAM) están evolucionando rápidamente y pueden ser relevantes para habilitar las capacidades deseadas.

Nivel de competencia requerido de las capacidades

Si bien identificar las capacidades necesarias para que un agente realice su trabajo es un paso crucial, es igualmente importante evaluar y definir el nivel de competencia requerido para cada una de estas capacidades. Esto implica establecer puntos de referencia específicos y métricas de rendimiento que deben cumplirse para que el agente y sus capacidades se consideren competentes. Estos puntos de referencia pueden incluir precisión, eficiencia y confiabilidad.

Por ejemplo, para nuestro agente de creación de contenido, los niveles de competencia deseados podrían incluir:

  • Fiabilidad de llamadas a funciones del 75%.
  • Explicabilidad de llamadas a funciones fallidas del 99,99%.
  • Función de llamada del agente de tendencias de contenido que da como resultado temas relevantes al menos el 75% de las veces en el primer intento.
  • Generación de ideas de contenidos que resultan en temas deseables el 75% de las veces.
  • Recuperación de información precisa con una tasa de precisión del 99,99%.
  • Generación de ediciones con una tasa de satisfacción de los comentarios de los usuarios del 90% o superior.
  • Generación de borradores finales con una tasa de satisfacción de los comentarios de los usuarios del 90% o superior.

Ingeniería y diseño de agentes

Mapeo de las competencias requeridas con tecnologías y técnicas

Una vez que se especifican las capacidades necesarias y los niveles de competencia requeridos, el siguiente paso es determinar cómo podemos cumplir con estos requisitos. Esto implica evaluar un arsenal de tecnologías y técnicas disponibles en rápido crecimiento, incluidos LLM, RAG, Guardrails, API especializadas y otros modelos de ML/AI para evaluar si pueden alcanzar los niveles de competencia especificados. En todos los casos, es útil considerar en qué es mejor una determinada tecnología o técnica a alto nivel y las implicaciones de costo/beneficio. Discutiré superficialmente algunos aquí, pero su alcance y escala serán limitados ya que existen innumerables posibilidades.

Amplio conocimiento

El conocimiento amplio se refiere a la comprensión general y la información sobre una amplia gama de temas y dominios. Este tipo de conocimiento es esencial para crear agentes de IA que puedan entablar un diálogo eficaz, comprender el contexto y proporcionar respuestas relevantes en diversos temas.

  • LLM: si las capacidades de su agente requieren un amplio conocimiento, la buena noticia es que el desarrollo de LLM continúa sin cesar. Desde modelos de código abierto como LlaMA3 hasta los últimos modelos propietarios de OpenAI, Anthropic y Google, no faltan opciones de tecnologías que brindan coherencia de alta densidad en una extensión tan vasta de lenguaje y conocimiento humanos.
  • Ingeniería prompt: esta área de desarrollo dinámica y muy activa se centra esencialmente en cómo activar los dominios de conocimiento contextualmente apropiados que son modelados por los LLM. Debido a las cualidades caleidoscópicas del lenguaje, el dominio de este arte puede tener un impacto dramático en los niveles de dominio de las capacidades de nuestro Agente.

Competencia en conocimientos específicos

El conocimiento específico implica una comprensión más profunda de dominios o temas particulares. Este tipo de conocimiento es necesario para tareas que requieren experiencia detallada y familiaridad con contenido especializado. ¿Qué tecnologías/técnicas podríamos considerar para alcanzar nuestros objetivos de competencia?

  • Generación aumentada de recuperación (RAG): RAG combina las capacidades generativas de los LLM con sistemas de recuperación de información para incorporar información de fuentes externas. Esto podría ser información precisa o conocimiento específico (por ejemplo, una descripción de un método único) que el LLM puede «comprender» en contexto debido a su amplio conocimiento.
  • Ajuste fino del modelo: los LLM de ajuste fino en conjuntos de datos específicos del contexto adaptan los modelos para generar respuestas más contextualmente relevantes en entornos particulares. Aunque no es tan popular como RAG, a medida que la ingeniería de agentes continúa ganando terreno, es posible que descubramos que los requisitos de competencia nos llevan hacia esta técnica con más frecuencia.

Información precisa

La información precisa se refiere a puntos de datos específicos y muy precisos que son críticos para tareas que requieren respuestas exactas.

  • Llamada de funciones (también conocida como uso de herramientas): todos desconfiamos del agente de IA que alucina con respecto a hechos específicos que son indiscutibles. Si el nivel requerido de competencia lo exige, podríamos recurrir a llamadas a funciones para recuperar la información específica. Por ejemplo, un agente de comercio electrónico podría utilizar una API de precios para proporcionar los precios más recientes de los productos o una API del mercado de valores para brindar actualizaciones en tiempo real sobre los valores de las acciones.
  • Guardrails: los Guardrails pueden ayudar a garantizar que el agente proporcione información precisa y exacta en sus respuestas. Esto puede implicar restricciones basadas en reglas, diseño conversacional dirigido y preprocesamiento de intenciones.

Anatomía y orquestación del agente

Ahora que tenemos una idea clara de cuál es el trabajo del Agente, las capacidades y niveles de competencia requeridos y las tecnologías disponibles para habilitarlos, cambiamos nuestro enfoque a la anatomía y orquestación del agente, ya sea en una configuración en solitario o en algún tipo de enjambre. o ecosistema. ¿Deberían registrarse las capacidades para un agente o cada capacidad debería asignarse a un agente único que opere dentro de un enjambre? ¿Cómo desarrollamos capacidades y agentes que puedan reutilizarse con el mínimo esfuerzo? Este tema por sí solo involucra varios artículos, por lo que no profundizaremos más en él aquí. En algunos aspectos, aquí es donde “la goma se encuentra con el camino” y nos encontramos entrelazando múltiples tecnologías y técnicas para dar vida a nuestros Agentes.

Conclusión

El viaje de la ingeniería de prompts a la ingeniería de agentes apenas comienza y hay mucho que aprender y perfeccionar a lo largo del camino. Este primer intento de crear un marco de ingeniería de agentes propone un enfoque práctico para diseñar agentes de IA al delinear un modelo mental de alto nivel que puede servir como un punto de partida útil en esa evolución. Los modelos y técnicas disponibles para crear Agentes seguirán proliferando, creando una clara necesidad de marcos que se generalicen lejos de cualquier tecnología o clase de tecnologías específica. Al definir claramente lo que un agente debe hacer, delinear las acciones necesarias para realizar estas tareas y especificar las capacidades y niveles de competencia necesarios, establecemos una base sólida y flexible para nuestros esfuerzos de diseño e ingeniería. Además, proporciona una estructura para que nuestros agentes y sus capacidades mejoren y evolucionen con el tiempo.

Gracias por leer y espero que el marco de ingeniería de agentes le resulte útil en tus esfuerzos orientados a los agentes. Estad atentos a futuras mejoras del marco y elaboraciones sobre los diversos temas mencionados. Si deseas hablar más sobre el marco u otros temas sobre los que he escrito, no dudes en conectar conmigo en LinkedIn.

A menos que se indique lo contrario, todas las imágenes de este artículo son del autor.

The post De la ingeniería prompt a la ingeniería de agentes first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/de-ingenieria-prompt-a-ingenieria-de-agentes/feed/ 0
RAG Agentic Con Llama-index | Capacidad de Razonamiento Multipaso #03 https://desa.planetachatbot.com/rag-agentic-con-llama-index-capacidad-de-razonamiento-multipaso-03/?utm_source=rss&utm_medium=rss&utm_campaign=rag-agentic-con-llama-index-capacidad-de-razonamiento-multipaso-03 https://desa.planetachatbot.com/rag-agentic-con-llama-index-capacidad-de-razonamiento-multipaso-03/#respond Wed, 31 Jul 2024 06:00:11 +0000 https://desa.planetachatbot.com/?p=18171 Bienvenido de nuevo a la tercera entrega de nuestra serie RAG de Agentic. En este artículo, abordaremos la limitación de los avisos de una sola vez de la que hablamos anteriormente. Hasta ahora, nos hemos centrado en los avisos de un solo paso, en los que las tareas se completan en un único bucle. Sin […]

The post RAG Agentic Con Llama-index | Capacidad de Razonamiento Multipaso #03 first appeared on Planeta Chatbot.

]]>
Bienvenido de nuevo a la tercera entrega de nuestra serie RAG de Agentic. En este artículo, abordaremos la limitación de los avisos de una sola vez de la que hablamos anteriormente. Hasta ahora, nos hemos centrado en los avisos de un solo paso, en los que las tareas se completan en un único bucle. Sin embargo, cuando se trata de tareas complejas que requieren un razonamiento de varios pasos, este enfoque se queda corto. Aquí es donde brillan los agentes, especialmente en el contexto de los LLM y las aplicaciones RAG Agentic.

En este artículo, exploraremos cómo implementar un bucle de razonamiento multipaso en nuestra arquitectura Agentic RAG. Prepárate para una emocionante inmersión profunda en el poder de los agentes y su capacidad para manejar intrincadas tareas de múltiples pasos con precisión y eficiencia. Puedes consultar los anteriores también en nuestra web, Planeta Chatbot:

Qué son los agentes

Hasta ahora hemos estado trabajando con Llama-index.

Los data agents son trabajadores del conocimiento potenciados por LLM en LlamaIndex que pueden realizar de forma inteligente diversas tareas sobre sus datos, tanto en función de «lectura» como de «escritura». Son capaces de lo siguiente:

  • Realizar búsquedas y recuperaciones automatizadas sobre diferentes tipos de datos: no estructurados, semiestructurados y estructurados.
  • Llamar a cualquier API de servicio externo de forma estructurada, y procesar la respuesta + almacenarla para más tarde.

En ese sentido, los agentes van un paso más allá de nuestros motores de consulta, ya que no sólo pueden «leer» de una fuente estática de datos, sino que pueden ingerir y modificar dinámicamente datos de una variedad de herramientas diferentes.

Construir un agente de datos requiere los siguientes componentes básicos:

  • Un bucle de razonamiento
  • Abstracciones de herramientas

Un data agent se inicializa con un conjunto de APIs, o Herramientas, con las que interactuar; el agente puede llamar a estas APIs para devolver información o modificar el estado. Dada una tarea de entrada, el data agent utiliza un bucle de razonamiento para decidir qué herramientas utilizar, en qué secuencia, y los parámetros para llamar a cada herramienta.

Por defecto los agentes en Llama-index se componen de dos cosas principales:

  1. AgentRunner: Esta es la parte del agente que se encarga de la orquestación de tareas aka Task Orchestrator. Esta sección del agente también maneja el Estado y la Memoria. El AgentWorker responde a esta sección del agente después de completar cada tarea que se le asigna, la respuesta se comunica al usuario si es necesario.
  2. AgentWorker: Es lo que realmente ejecuta y razona las tareas. Las tareas son delegadas a esta sección del flujo de trabajo del agente por el AgentRunner. Se ocupa de las Herramientas y LLMs.

Recursos de vídeo

Si te gusta ver vídeos en lugar de leer, también tengo algo para ti.

Configuración del entorno

Utilizaremos el mismo entorno que configuramos en el artículo anterior. Lo único que crearé es un archivo .ipynb, este archivo se llama Lesson_03.ipynb:

Creando Herramientas

Vamos a seguir adelante y crear dos herramientas principales como ya hemos hecho en los últimos artículos.

import dotenv
%load_ext dotenv
%dotenv

import nest_asyncio
nest_asyncio.apply()
from llama_index.core import SimpleDirectoryReader

# load lora_paper.pdf documents
documents = SimpleDirectoryReader(input_files=["./datasets/lora_paper.pdf"]).load_data()

from llama_index.core.node_parser import SentenceSplitter

# chunk_size of 1024 is a good default value
splitter = SentenceSplitter(chunk_size=1024)
# Create nodes from documents
nodes = splitter.get_nodes_from_documents(documents)

from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

# LLM model
Settings.llm = OpenAI(model="gpt-3.5-turbo")
# embedding model
Settings.embed_model = OpenAIEmbedding(model="text-embedding-ada-002")
from llama_index.core import SummaryIndex, VectorStoreIndex

# summary index
summary_index = SummaryIndex(nodes)
# vector store index
vector_index = VectorStoreIndex(nodes)

# summary query engine
summary_query_engine = summary_index.as_query_engine(
    response_mode="tree_summarize",
    use_async=True,
)

# vector query engine
vector_query_engine = vector_index.as_query_engine()
llm = OpenAI(model="gpt-3.5-turbo", temperature=0)
from llama_index.core.tools import QueryEngineTool
summary_tool = QueryEngineTool.from_defaults(
query_engine=summary_query_engine,
description=(
"Useful for summarization questions related to the Lora paper."
),
)

vector_tool = QueryEngineTool.from_defaults(
query_engine=vector_query_engine,
description=(
"Useful for retrieving specific context from the the Lora paper."
),
)

Bucle de razonamiento

El bucle de razonamiento depende del tipo de agente.

Tenemos soporte para los siguientes agentes:

  • Agentes de llamada a función (se integra con cualquier LLM de llamada a función).
  • Agente ReAct (funciona a través de cualquier endpoint de finalización de chat/texto).

«Agentes avanzados: LLMCompiler (https://llamahub.ai/l/llama-packs/llama-index-packs-agents-llm-compiler?from=), Chain-of-Abstraction (https://llamahub.ai/l/llama-packs/llama-index-packs-agents-coa?from=), Language Agent Tree Search (https://llamahub.ai/l/llama-packs/llama-index-packs-agents-lats?from=), y más.

AgentWorker

Como hemos comentado anteriormente, el agent worker es el responsable de ejecutar todas las herramientas y los LLMs. Vamos a crear un agent worker pasándole todas las herramientas que hemos creado anteriormente:

from llama_index.core.agent import FunctionCallingAgentWorker
from llama_index.core.agent import AgentRunner

agent_worker = FunctionCallingAgentWorker.from_tools(
tools=[vector_tool, summary_tool],
llm=llm,
verbose=True
)
agent = AgentRunner(agent_worker)

Para ello, utilicemos una pregunta que requiera un razonamiento de varios pasos.

response = agent.query(
"Explain to me what is Lora and why it's being used. Are existing solutions not good enough?"
)

En la imagen de arriba, se puede ver que el LLM está haciendo uso de una cadena de razonamiento CoT para responder a todas las preguntas que le habíamos planteado, una tras otra, basándose en la anterior.

Memoria de conversaciones

Hasta ahora, la arquitectura de agentes RAG funciona bien. Una limitación es que no recuerda conversaciones anteriores. Tenemos la capacidad de mantener una memoria tal que las acciones que realiza el agente no sólo dependen de la consulta del usuario, sino que también se tiene en cuenta el historial de las conversaciones anteriores con los agentes.

La memoria no es más que una lista plana de conversaciones que el agente ha mantenido con el usuario. Esta lista es un buffer de memoria conversacional, la razón es que no queremos tener demasiada conversación almacenada en memoria de tal forma que desbordemos la ventana de contexto de los LLMs. Esta lista actúa como un buffer rodante dependiendo del tamaño de la ventana de contexto del LLM subyacente que estemos usando.

Para utilizar la capacidad de memoria del agente, tenemos que llamar al método chat() en lugar del método query() que hemos utilizado hasta ahora. El método query() no conserva el estado, por lo que no se conserva el historial de la conversación.

response = agent.chat(
"Explain to me what is Lora and why it's being used. Are existing solutions not good enough?"
)

print(str(response))
response = agent.chat(
"What was my last question to you?"
)

print(str(response))

Cómo funciona a bajo nivel

Hemos visto cómo funciona el agente desde una perspectiva de alto nivel. Echemos un vistazo a cómo funciona en un nivel inferior y obtengamos más control sobre la ejecución del agente y cómo se llevan a cabo las tareas. Esto nos da algunas ventajas añadidas como:

  1. Programar nuestras propias tareas: Podemos controlar y programar nuestras propias tareas y establecer cuando se ejecutará cada tarea.
  2. Incorporar feedback humano: Entendiendo cómo funciona el agente a un nivel inferior, podemos ser capaces de proporcionar manualmente feedback humano al agente para hacerle saber si está dando los pasos correctos que queremos o no, en caso contrario podemos especificar manualmente al agente qué acciones queremos que realice.
  3. Ayuda a la resolución de problemas

En primer lugar, vamos a seguir adelante y crear un agente de ejecución, que se ejecuta el agente de trabajo como hemos discutido anteriormente.

agent_worker = FunctionCallingAgentWorker.from_tools(
[vector_tool, summary_tool],
llm=llm,
verbose=True
)
agent = AgentRunner(agent_worker)

Ahora vamos a crear manualmente una tarea para el agentrunner Orchestrator:

task = agent.create_task(
"Explain to me what is Lora and why it's being used."
"Are existing solutions not good enough?"
)

Una vez que tenemos esta tarea creada, recuerda que no pasamos esta tarea al agent worker por lo que no se ejecuta. Así que si comprobamos si se ha completado alguna tarea, deberíamos obtener cero, veamos esto en acción:

completed_steps = agent.get_completed_steps(task.task_id)

print(f"Number of completed steps for tasksID {task.task_id} is {len(completed_steps)}")

if len(completed_steps) > 0:
print(completed_steps[0].output.sources[0].raw_output)

Ahora, vamos a comprobar si el agentrunner ha orquestado algunas tareas para que las ejecute el agent worker. Podemos ver esto viendo las próximas tareas:

upcoming_steps = agent.get_upcoming_steps(task.task_id)
print(f"Number of completed steps for tasksID {task.task_id} is {len(upcoming_steps)}")

if len(upcoming_steps) > 0:
print(upcoming_steps[0].input)

Desde aquí podemos ver la entrada que el agentrunner debe pasar al agent worker para que la ejecute. La entrada es la pregunta original que pasamos a la tarea que acabamos de crear. Ahora, vamos a seguir adelante y ejecutar la próxima tarea programada para ver y volvemos.

step_output = agent.run_step(task.task_id)

Se puede ver que el agent worker fue capaz de razonar sobre la tarea e identificó que necesitaba dividir la tarea en dos subtareas separadas. Cada subtarea se resolvió mediante el uso de la herramienta de llamada aka función de llamada a la herramienta de motor de consulta en este caso particular.

Una vez hecho esto, podemos seguir adelante para comprobar si hay otras tareas que tenemos que completar y cuáles son sus entradas:

También podemos comprobar si este es el último paso que necesitábamos ejecutar:

print(step_output.is_last)

Se puede ver que hemos obtenido True, concretamente, un Python true indicando que era el último paso en la ejecución de la tarea.

También podemos sobreescribirlo proporcionando nuestras tareas personalizadas, esto puede actuar como un humano corrigiendo al agente sobre lo que necesita hacer, una especie de feedback guía humano.

Para ello, voy a crear una nueva tarea, y luego añadir la retroalimentación humana en el bucle y cambiar la pregunta de la tarea.

task = agent.create_task(
"Explain to me what is Lora and why it's being used."
"Are existing solutions not good enough?"
)

step_output = agent.run_step(
task.task_id, input="Explain to me the dataset used to fine-tune in the Lora paper."
)

Tenemos que comprobar si es el último paso, esto es importante o te dará un error. No sé por qué tuvieron que hacer eso.

RAG

Una vez hecho esto, podemos pasar a obtener la respuesta definitiva:

response = agent.finalize_response(task.task_id)
print(str(response))

Conclusión

Enhorabuena por haber llegado hasta aquí. En este artículo hemos repasado cómo trabajar con un bucle de razonamiento multipaso en un sistema RAG agéntico. No sólo hemos visto la implementación de alto nivel, sino también el funcionamiento a bajo nivel del bucle de razonamiento multipaso y la posibilidad de proporcionar feedback al agente (feedback humano en el bucle).

Espero que este artículo te proporcione una clara comprensión de la capacidad de razonamiento multipaso de un agente. En el próximo artículo, veremos cómo realizar capacidades RAG utilizando múltiples documentos.

Otras plataformas en las que puedes ponerte en contacto conmigo:

  1. YouTube
  2. Twitter
  3. LinkedIn
  4. Discord

Referencias

  1. Data Agents Llama-index

The post RAG Agentic Con Llama-index | Capacidad de Razonamiento Multipaso #03 first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/rag-agentic-con-llama-index-capacidad-de-razonamiento-multipaso-03/feed/ 0
Cómo crear agentes de IA generativa a escala empresarial con AWS Bedrock: Una guía completa https://desa.planetachatbot.com/como-crear-agentes-de-ia-generativa-a-escala-empresarial-con-aws-bedrock-una-guia-completa/?utm_source=rss&utm_medium=rss&utm_campaign=como-crear-agentes-de-ia-generativa-a-escala-empresarial-con-aws-bedrock-una-guia-completa https://desa.planetachatbot.com/como-crear-agentes-de-ia-generativa-a-escala-empresarial-con-aws-bedrock-una-guia-completa/#respond Thu, 18 Jul 2024 06:00:53 +0000 https://desa.planetachatbot.com/?p=18093 La IA generativa se está convirtiendo cada vez más en una parte integral de las aplicaciones empresariales, impulsando la innovación y la eficiencia en diversos sectores. Un reto importante a la hora de aprovechar esta tecnología, sobre todo cuando se utilizan plataformas como ChatGPT o alternativas similares, y herramientas de terceros para el desarrollo de […]

The post Cómo crear agentes de IA generativa a escala empresarial con AWS Bedrock: Una guía completa first appeared on Planeta Chatbot.

]]>
La IA generativa se está convirtiendo cada vez más en una parte integral de las aplicaciones empresariales, impulsando la innovación y la eficiencia en diversos sectores. Un reto importante a la hora de aprovechar esta tecnología, sobre todo cuando se utilizan plataformas como ChatGPT o alternativas similares, y herramientas de terceros para el desarrollo de chatbots, es la gestión de los datos confidenciales de la empresa. A menudo, las empresas se enfrentan al dilema de aprovechar las capacidades avanzadas de la IA y, al mismo tiempo, garantizar la seguridad y la gobernanza de su información confidencial.

Amazon Web Services (AWS) ofrece una solución a este desafío a través de AWS Bedrock y un conjunto de servicios de AWS diseñados para crear agentes de IA conversacionales que puedan gestionar y utilizar de forma segura los datos de propiedad. AWS Bedrock, junto con el sólido ecosistema de AWS, ofrece un marco en el que la seguridad y la gobernanza están en primer plano, lo que garantiza que las empresas puedan aprovechar el poder de la IA generativa sin comprometer la protección de los datos.

En este tutorial práctico, profundizaremos en la creación de un agente de IA conversacional que utiliza documentos propios almacenados en Amazon S3. Este agente de IA será capaz de recuperar información relevante de nuestra base de datos mediante Retrieval-Augmented Generation (RAG) y AWS OpenSearch Vector Database, mostrando la integración perfecta y las potentes capacidades de los servicios de AWS para manejar tareas complejas de recuperación de datos.

Para que este agente de IA sea accesible, desarrollaremos una API utilizando AWS Lambda y API Gateway, garantizando una interfaz escalable y segura para la interacción. Además, para mejorar la experiencia del usuario, emplearemos Voiceflow para el front-end, lo que permitirá una interfaz conversacional intuitiva y atractiva.

La arquitectura

El siguiente diagrama es un patrón de arquitectura de solución común que puedes utilizar para integrar cualquier aplicación de chatbot a Knowledge Bases para Amazon Bedrock. Utilizaremos este diagrama como base para el back-end de nuestra aplicación y lo integraremos a través de una API en nuestra interfaz de chat Voiceflow.

IA generativa

Esta arquitectura incluye los siguientes pasos:

  • Consulta del usuario: Un usuario inicia el proceso interactuando con el chatbot a través de una solicitud de API iniciada a través de la interfaz de chat front-end de Voiceflow, emitiendo una pregunta en lenguaje natural.
  • La API activa AWS Lambda: La API recibe la consulta y activa una función de AWS Lambda. Esta función es responsable del procesamiento posterior de la consulta del usuario.
  • Invocar la API RetrieveAndGenerate: Dentro de la función de AWS Lambda, se procesa la consulta del usuario y se invoca la API RetrieveAndGenerate de Amazon Bedrock.
  • Conversión de la consulta en vector: A continuación, la consulta del usuario se convierte en un vector mediante un modelo de incrustación de Amazon Titan dentro de Amazon Bedrock.
  • Recuperación de información relevante: Tras convertir la consulta, el sistema extrae segmentos de datos de la base de conocimientos que se alinean semánticamente con la consulta del usuario. Este proceso se realiza mediante la comparación de la representación vectorial de la consulta con las incrustaciones de texto almacenadas en un almacén vectorial de Amazon OpenSearch Serverless.
  • Aumento de la consulta del usuario: La información recuperada se utiliza para aumentar la consulta original del usuario, añadiendo contexto adicional que es fundamental para generar una respuesta precisa y contextualmente relevante.
  • Generación de la respuesta con LLM: esta instrucción enriquecida se utiliza como entrada para un modelo de lenguaje amplio (LLM), como Anthropic Claude 2, disponible en Amazon Bedrock. A partir del contexto enriquecido, el LLM genera una respuesta completa y pertinente.
  • Envío de la respuesta al usuario: La respuesta elaborada por el LLM se envía de vuelta al usuario a través de la API al front-end Voiceflow, donde se muestra al usuario.

La siguiente sección proporciona una guía detallada paso a paso sobre la construcción de un agente de IA conversacional utilizando varios servicios de AWS y Voiceflow. Para participar y seguir la guía, asegúrate de tener una cuenta de AWS activa. También puedes encontrar una copia del código fuente en GitHub.

La base de datos de conocimientos

Carga tu conjunto de datos de conocimiento en Amazon S3

Encuentra un conjunto de datos que te gustaría que tu Agente de IA consultara. Procederemos a cargar este conjunto de datos en un bucket de Amazon S3 y a configurar una base de datos de conocimientos para interactuar con el conjunto de datos elegido de forma eficaz.

Completa los siguientes pasos:

  1. En la consola de Amazon S3, selecciona Buckets en el panel de navegación.
  2. Haz clic en Crear bucket.
  3. Nombra el bucket knowledgebase-<chatbot-name>.
  4. Deja el resto de la configuración del bucket como predeterminada y seleccione Crear.
  5. Navega hasta el bucket knowledgebase-<chatbot-name>.
  6. Selecciona «Crear carpeta» y nómbrala dataset.
  7. Deja el resto de configuraciones de carpeta por defecto y elija Crear.
  8. Ve a la carpeta del conjunto de datos.
  9. Arrastra y suelta el conjunto de datos que descargaste anteriormente en este bucket y selecciona Cargar.
  10. Vuelve al inicio del bucket y elige «Crear carpeta» para crear una nueva carpeta y nómbrala lambdalayer.
  11. Deja todos los demás ajustes por defecto y crea la carpeta.
  1. Navega hasta la carpeta lambdalayer.
  2. Sube el archivo knowledgebase-lambdalayer.zip disponible en la carpeta /data/lambda_layer en GitHub y selecciona Upload. Utilizarás este código de capa lambda más adelante para crear la función lambda.

Crear una base de conocimientos

  1. En este paso, crearemos una base de conocimientos utilizando el conjunto de datos que subimos al bucket de S3 en el paso anterior.
    En la consola de Amazon Bedrock, navega hasta la sección Orchestration y selecciona Knowledge Base. Es importante tener en cuenta que, en el momento de escribir este artículo, la función de base de datos de conocimientos solo está disponible en determinadas regiones. Por lo tanto, para este tutorial, utilizaremos us-east-1 como región predeterminada.
  2. Selecciona «Crear base de conocimientos».
  3. En la sección «Detalles de la base de conocimientos», introduce un nombre y una descripción opcional.
  4. En la sección Permisos IAM, selecciona «Crear «y utiliza un nuevo rol de servicio e introduzca un nombre para el rol.
  5. Selecciona Siguiente.
  6. En la sección Fuente de datos, deja «Nombre de fuente de datos» como nombre predeterminado.
  7. En URI de S3, seleccione Examinar S3 para elegir el bucket de S3 knowledgebase-<chatbot-name>/dataset/. Debes apuntar al bucket de S3 y a la carpeta del conjunto de datos que creó en los pasos anteriores.
  8. En la sección Configuración avanzada, deja los valores predeterminados (si lo deseas, puedes cambiar la estrategia de fragmentación predeterminada y especificar el tamaño de los trozos y la superposición en porcentaje).
  9. Selecciona «Siguiente».
  10. En la sección Modelo de incrustación, selecciona «Incrustación Titan G1 – Texto para el modelo de incrustación».
  11. En la sección Base de datos vectorial, seleccionea «Crear» rápidamente un nuevo almacén vectorial, esto crea un nuevo almacén vectorial OpenSearch Serverless en su cuenta.
  12. Selecciona Siguiente.
  13. En la página Revisar y crear, revisa toda la información o selecciona Anterior para modificar cualquier opción.
  14. Selecciona Crear base de conocimientos. Observa que comienza el proceso de creación de la base de conocimientos y que el estado es En curso. La creación del almacén de vectores y de la base de conocimientos tardará unos minutos. No abandones la página, de lo contrario la creación fallará.
  15. Cuando el estado de la base de conocimientos sea «Listo», anota el ID de la base de conocimientos. Lo utilizarás en los próximos pasos para configurar la función Lambda.
  16. Ahora que la base de conocimientos está lista, tenemos que sincronizar nuestro conjunto de datos personalizado con ella. En la sección «Fuente de datos» de la página de detalles de la base de conocimientos, seleccione Sincronizar para activar el proceso de ingestión de datos desde el bucket de S3 a la base de conocimientos.
  17. Este proceso de sincronización divide los archivos de documentos en trozos más pequeños del tamaño especificado anteriormente, genera incrustaciones vectoriales utilizando el modelo de incrustación de texto seleccionado y los almacena en el almacén vectorial administrado por Knowledge Bases para Amazon Bedrock.
  18. Cuando se complete la sincronización del conjunto de datos, el estado de la fuente de datos cambiará al estado Listo. Ten en cuenta que, si añades documentos adicionales en la carpeta de datos de S3, deberás volver a sincronizar la base de conocimientos.

Nuestra base de conocimientos ya está lista. Ten en cuenta que también puede utilizar las API del servicio Knowledge Bases for Amazon Bedrock y la CLI de AWS para crear una base de conocimientos mediante programación.

La función Lambda y la puerta de enlace API

En esta sección, construiremos una API diseñada para activar una función Lambda, que gestionará las consultas de los usuarios mediante la integración de AWS Bedrock y la base de conocimientos establecida previamente. Para simplificar la implementación y el desarrollo, se utilizará el marco Serverless para construir e implementar la infraestructura backend.

Iniciar el marco Serverless

Para obtener información sobre la instalación de Serverless, consulte esta página de instrucciones. Para iniciar un nuevo proyecto Serveless ejecute:

# initate a new serverless project
serverless

> select AWS - Python - HTTP API

> name your project

> Register or Login to Serverless Framework: n enter

> Do you want to deploy now?: n enter

A continuación, configuraremos nuestra infraestructura de back-end en el archivo serverless.yml.

service: knowledge-base-api
frameworkVersion: "3"

provider:
name: aws
runtime: python3.12
stage: dev
region: us-east-1
environment:
KNOWLEDGE_BASE_ID: ${self:custom.knowledgeBaseID}
iam:
role:
statements:
- Effect: "Allow"
Action:
- "bedrock:InvokeModel"
- "bedrock:Retrieve"
- "bedrock:RetrieveAndGenerate"
Resource: "*"

custom:
knowledgeBaseID: "<your knowledgebase ID>"
lambdaLayerS3BucketName: "<your S3 bucket name>"

functions:
invokeKnowledgeBase:
handler: handler.lambda_handler
memorySize: 256
timeout: 60
layers:
- { Ref: DeployKnowledgeBaseLambdaLayer }
events:
- http:
path: /
method: get
cors: true
resources:
Resources:
DeployKnowledgeBaseLambdaLayer:
Type: AWS::Lambda::LayerVersion
Properties:
LayerName: KnowledgeBaseLambdaLayer
Description: Knowledge Base Lambda Layer
Content:
S3Bucket: ${self:custom.lambdaLayerS3BucketName}
S3Key: lambdalayer/knowledgebase_lambdalayer.zip
CompatibleRuntimes:
- python3.12
- python3.11
- python3.10

Este archivo serverless.yml describe la configuración para implementar un servicio de API de base de conocimientos mediante el marco Serverless en AWS. El servicio, llamado knowledge-base-api, especifica AWS como el proveedor de la nube, utilizando Python 3.12 como el entorno de tiempo de ejecución en la etapa dev dentro de la región us-east-1. Las variables de entorno están configuradas, incluyendo un KNOWLEDGE_BASE_ID, que anotamos en el paso 15 de la Creación de Knowlege Base.

El rol de IAM definido en la configuración del proveedor concede al servicio permiso para realizar acciones como invocar modelos y recuperar datos mediante las API de Amazon Bedrock (bedrock:InvokeModel, bedrock:Retrieve y bedrock:RetrieveAndGenerate), con los permisos asignados a todos los recursos (Resource: «*») para simplificar y ampliar el acceso en este ejemplo.

La sección personalizada incluye marcadores de posición para especificar el knowledgeBaseID y el nombre de un bucket de S3 (knowledgebase-<chatbot-name>) donde se almacena la capa Lambda para la base de conocimientos.

Se detalla una única función, invokeKnowledgeBase, con handler.lambda_handler indicando el punto de entrada para la función Lambda. Está configurada para utilizar 256 MB de memoria y tiene un tiempo de espera de 60 segundos. Esta función está asociada a un evento HTTP GET, por lo que es accesible a través de un punto final RESTful, y CORS está habilitado para solicitudes de origen cruzado. La función también incluye una capa Lambda, DeployKnowledgeBaseLambdaLayer, que se define en la sección de recursos.

En el bloque de recursos, DeployKnowledgeBaseLambdaLayer se configura para crear una versión de la capa Lambda, que encapsula el código adicional o las bibliotecas que necesita la función Lambda. Esta capa se denomina KnowledgeBaseLambdaLayer y obtiene su contenido del bucket de S3 (knowledgebase-<chatbot-name>/lambdalayer). La capa es compatible con varios tiempos de ejecución de Python, lo que garantiza la flexibilidad entre diferentes versiones de Python.

Crear la función Lambda

En esta sección, nos sumergiremos en la creación de una función Lambda que forma la columna vertebral de nuestra aplicación de IA conversacional. Esta función es responsable de procesar las consultas de los usuarios, aprovechando el potente servicio AWS Bedrock para obtener y generar respuestas de nuestra base de conocimientos. Desglosaremos la función en pasos manejables, explicando el propósito y la funcionalidad de cada parte.

import os
import boto3
import json

boto3_session = boto3.session.Session()
region = boto3_session.region_name

La función comienza importando las bibliotecas necesarias. os se utiliza para acceder a variables de entorno, boto3 para AWS SDK para interactuar con los servicios de AWS y json para manejar estructuras de datos JSON. A continuación, inicializa una sesión de boto3 y recupera la región de AWS en la que se implementa la función Lambda.

bedrock_agent_runtime_client = boto3.client('bedrock-agent-runtime', region_name="us-east-1")

Esta línea crea un cliente Boto3 para el tiempo de ejecución del agente Bedrock, especificando la región (aquí, «us-east-1»). Este cliente se utiliza para interactuar con AWS Bedrock, específicamente para invocar la API retrieve_and_generate.

def lambda_handler(event, context):
# Extract the question and session ID from the event
question = event[«queryStringParameters»][«question»]

try:
session_id = event[«queryStringParameters»][«session_id»]
except:
session_id = «None»

# Assuming you’ve set the KNOWLEDGE_BASE_ID as an environment variable in your Lambda function
kb_id = os.environ[«KNOWLEDGE_BASE_ID»]

# Specify the model ID and construct its ARN. Update these placeholders as needed.
model_id = «anthropic.claude-v2»
region = «us-east-1»
model_arn = f’arn:aws:bedrock:{region}::foundation-model/{model_id}’

# Call the retrieve and generate function
response = retrieveAndGenerate(question, kb_id, model_arn, session_id)

# Extract the generated text and session ID from the response
generated_text = response[‘output’][‘text’]
session_id = response.get(‘sessionId’, »)

headers = {
«Access-Control-Allow-Origin»: «*»,
«Access-Control-Allow-Credentials»: True
}
# Return the response in the expected format
return {
‘statusCode’: 200,
‘headers’: headers,
‘body’: json.dumps({
«question»: question.strip(),
«answer»: generated_text.strip(),
«sessionId»: session_id
}, ensure_ascii=False)
}

La función lambda_handler actúa como puerta de enlace entre AWS Lambda y el mundo exterior, en este caso, principalmente AWS API Gateway que activa esta función de Lambda. Cuando un usuario envía una consulta a través de la interfaz de front-end, esta función entra en acción. Comienza analizando la solicitud entrante, buscando específicamente la pregunta y, opcionalmente, un session_id en los parámetros de consulta. Estos parámetros son esenciales para mantener un flujo de diálogo continuo y proporcionar contexto al modelo de IA para generar respuestas relevantes.

Tras extraer la información necesaria del objeto de evento, lambda_handler procede a recopilar detalles de configuración adicionales. Recupera el ID de la base de conocimientos (kb_id) de las variables de entorno y, a continuación, construye el ARN del modelo, que identifica de forma exclusiva el modelo de IA que se utilizará para generar las respuestas. Este ARN incluye la región y el identificador específico del modelo. En este tutorial, utilizaremos el modelo Claude 2 de Anthropic (anthropic.claude-v2).

def retrieveAndGenerate(question, kbId, model_arn, sessionId=None):
if sessionId != "None":
return bedrock_agent_runtime_client.retrieve_and_generate(
input={
'text': question
},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': kbId,
'modelArn': model_arn
}
},
sessionId=sessionId
)
else:
return bedrock_agent_runtime_client.retrieve_and_generate(
input={
'text': question
},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': kbId,
'modelArn': model_arn
}
}
)

Con toda la información y las configuraciones necesarias a mano, lambda_handler llama a la función retrieveAndGenerate. La función retrieveAndGenerate interactúa con la API Retrieve and Generate de AWS Bedrock. Toma la pregunta del usuario, el ID de la base de conocimientos, el ARN del modelo y un ID de sesión opcional, y llama a la API de Bedrock para generar una respuesta basada en el contenido de la base de conocimientos.

El session_id es un identificador único que permite el seguimiento y la gestión de sesiones de usuario individuales en una aplicación de IA conversacional, facilitando respuestas contextualizadas al preservar el historial de diálogo a través de las interacciones del usuario. Esto permite a la IA proporcionar respuestas coherentes y contextualmente relevantes, mejorando la experiencia del usuario al hacer que la conversación resulte más natural y atractiva.

Por último, la función lambda_handler formatea y devuelve esta respuesta como un objeto JSON estructurado, garantizando la compatibilidad con las aplicaciones web mediante las cabeceras CORS adecuadas y un código de estado HTTP estándar.

A continuación, puedes encontrar el código completo de la función Lambda.

import os
import boto3
import json

boto3_session = boto3.session.Session()
region = boto3_session.region_name

# create a boto3 bedrock client
bedrock_agent_runtime_client = boto3.client('bedrock-agent-runtime',region_name="us-east-1")

def retrieveAndGenerate(question, kbId, model_arn, sessionId=None):
if sessionId != "None":
return bedrock_agent_runtime_client.retrieve_and_generate(
input={
'text': question
},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': kbId,
'modelArn': model_arn
}
},
sessionId=sessionId
)
else:
return bedrock_agent_runtime_client.retrieve_and_generate(
input={
'text': question
},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': kbId,
'modelArn': model_arn
}
}
)

def lambda_handler(event, context):
# Extract the question and session ID from the event
question = event["queryStringParameters"]["question"]

try:
session_id = event["queryStringParameters"]["session_id"]
except:
session_id = "None"

# Assuming you've set the KNOWLEDGE_BASE_ID as an environment variable in your Lambda function
kb_id = os.environ["KNOWLEDGE_BASE_ID"]

# Specify the model ID and construct its ARN. Update these placeholders as needed.
model_id = "anthropic.claude-v2"
region = "us-east-1"
model_arn = f'arn:aws:bedrock:{region}::foundation-model/{model_id}'

# Call the retrieve and generate function
response = retrieveAndGenerate(question, kb_id, model_arn, session_id)

# Extract the generated text and session ID from the response
generated_text = response['output']['text']
session_id = response.get('sessionId', '')

headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": True
}
# Return the response in the expected format
return {
'statusCode': 200,
'headers': headers,
'body': json.dumps({
"question": question.strip(),
"answer": generated_text.strip(),
"sessionId": session_id
}, ensure_ascii=False)
}

Al desplegar la infraestructura Serverless (serverless deploy), obtenemos una dirección API que podemos utilizar para interactuar con nuestro agente de IA:

https://<API ID>.execute-api.us-east-1.amazonaws.com/dev/?question=<your question>&session_id=<your session ID>

Voiceflow Frontend

Para integrar perfectamente nuestra API en una interfaz de chatbot, empleamos Voiceflow junto con los servicios de AWS. Esta potente combinación garantiza que nuestro chatbot no solo reciba a los usuarios con calidez, sino que también responda de forma inteligente a sus consultas e integre respuestas alternativas en caso de que fallen las solicitudes de API.

Al iniciar una conversación, el usuario recibe un amistoso mensaje de bienvenida del chatbot. A continuación, el chatbot espera la respuesta del usuario y la captura para una acción posterior. Esta entrada actúa como disparador para el bloque de solicitud GET, preconfigurado en Voiceflow para llegar a nuestra API externa, el punto final de nuestra función AWS Lambda. Una vez recibida la consulta del usuario, el bloque de solicitud GET la envía a nuestra función Lambda, donde se genera una respuesta adecuada que se envía de vuelta a través de nuestra API. Si la llamada a la API tiene éxito, el siguiente bloque de Voiceflow mostrará la respuesta de la función Lambda directamente al usuario.

Sin embargo, si hubiera algún problema en la obtención de la respuesta, Voiceflow está diseñado para manejar estas anomalías con elegancia. Se crea un mensaje de error que informa al usuario del problema y le invita a continuar la conversación. Este cuidadoso diseño garantiza que el chatbot siga siendo atractivo y útil, incluso cuando surgen circunstancias imprevistas. Tras una respuesta satisfactoria, el usuario puede formular una nueva pregunta. En las siguientes llamadas a la API, se transmite el identificador de sesión generado durante la interacción inicial, lo que garantiza una conversación fluida y coherente al mantener el contexto del viaje del usuario.

Conclusión

Hemos llegado al final de nuestro exhaustivo viaje a través de la creación de un agente de IA generativa a escala empresarial con AWS Bedrock. Desde la configuración de una interfaz de chatbot acogedora en Voiceflow, hasta los intrincados procesos de back-end que implican AWS Lambda, API Gateway, Bedrock y Knowledge Bases, hemos explorado un enfoque de desarrollo de pila completa que prioriza la seguridad y el manejo eficiente de los datos. Hemos visto cómo almacenar y recuperar información con los servicios de AWS, y cómo entrelazar estos elementos en una experiencia conversacional sin fisuras utilizando el marco Serverless.

El tutorial te ha equipado con los conocimientos prácticos para implementar datos propios en interacciones de IA, garantizando un diálogo continuo y consciente del contexto con la administración de sesiones. Este conocimiento establece una base sólida para crear agentes de IA inteligentes que no solo entienden y responden a las consultas de los usuarios, sino que lo hacen con una gran conciencia de la seguridad y la gobernanza de los datos empresariales.

Sigue mi página de Instagram, LinkedIn o visita mi página web https://www.pairrot.eu/ para obtener más contenido relacionado con la IA.

The post Cómo crear agentes de IA generativa a escala empresarial con AWS Bedrock: Una guía completa first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/como-crear-agentes-de-ia-generativa-a-escala-empresarial-con-aws-bedrock-una-guia-completa/feed/ 0
¿Cómo usar ChatGPT y otras IAs de manera privada? https://desa.planetachatbot.com/como-usar-chatgpt-y-otras-ias-de-manera-privada/?utm_source=rss&utm_medium=rss&utm_campaign=como-usar-chatgpt-y-otras-ias-de-manera-privada https://desa.planetachatbot.com/como-usar-chatgpt-y-otras-ias-de-manera-privada/#respond Wed, 17 Jul 2024 06:00:37 +0000 https://desa.planetachatbot.com/?p=17952 Inteligencia Artifical privada al alcance de todos. DuckDuckGo anonimiza los chats de IA.

The post ¿Cómo usar ChatGPT y otras IAs de manera privada? first appeared on Planeta Chatbot.

]]>

Inteligencia Artificial privada al alcance de todos. A medida que la Inteligencia Artificial (IA) se vuelve más sofisticada y útil en nuestras tareas cotidianas, surgen nuevas preocupaciones sobre la privacidad al interactuar con los «chatbots». La herramienta DuckDuckGo, comprometida con la privacidad, ofrece una solución innovadora: utilizar ChatGPT y otros «chatbots» sin necesidad de crear una cuenta personal. DuckDuckGo, la empresa detrás del motor de búsqueda centrado en la privacidad, ha anunciado DuckDuckGo AI Chat, una forma gratuita, opcional y anónima de acceder a cuatro populares chatbots de IA generativa. La compañía dijo que con AI Chat, podrás acceder a GPT 3.5 Turbo de OpenAI, Claude 3 Haiku de Anthropic, Meta Llama 3 y Mixtral 8x7B de Mistral ahora, y planea añadir el acceso a otros modelos de chatbot en el futuro.

¿Cómo se mantiene la privacidad?

DuckDuckGo anonimiza los chats de IA. La empresa se interpone entre el usuario y los modelos, eliminando tu dirección IP de los chats y sustituyéndola por la de DuckDuckGo.

Además, DuckDuckGo también dice que tiene un acuerdo con los proveedores de modelos para eliminar todos los chats guardados en un plazo de 30 días desde su creación. La empresa afirmó que este acuerdo también garantiza que «ninguno de los chats realizados en nuestra plataforma puede utilizarse para entrenar o mejorar los modelos.»

Inteligencia Artificial privada al alcance de todos

Aunque AI Chat es gratuito, tiene un límite de uso diario. DuckDuckGo también ha dicho que está estudiando la posibilidad de crear una versión de pago de AI Chat que aumentaría este límite diario y daría acceso a modelos de IA más costosos. Cuanto más potente es el modelo de IA, más caro resulta ejecutarlo, razón por la cual muchas herramientas de IA ofrecen acceso de pago a herramientas más sofisticadas además de sus versiones gratuitas.

De momento, si quieres probar AI Chat, puedes ir a duck.ai o duckduckgo.com/chat. Se te pedirá que elijas el modelo de IA con el que quieres chatear y listo. Puedes cambiar de modelo más tarde haciendo clic en el nombre del modelo en la barra de herramientas izquierda del chat y seleccionando otro modelo. Puedes borrar un chat haciendo clic en el icono de la llama a la izquierda de la barra de texto.

The post ¿Cómo usar ChatGPT y otras IAs de manera privada? first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/como-usar-chatgpt-y-otras-ias-de-manera-privada/feed/ 0
Agentic RAG con Llama-index | Llamada a función #02 https://desa.planetachatbot.com/agentic-rag-con-llama-index-llamada-a-funcion-02/?utm_source=rss&utm_medium=rss&utm_campaign=agentic-rag-con-llama-index-llamada-a-funcion-02 https://desa.planetachatbot.com/agentic-rag-con-llama-index-llamada-a-funcion-02/#respond Wed, 10 Jul 2024 06:00:23 +0000 https://desa.planetachatbot.com/?p=18070 En este artículo, profundizamos en los fundamentos de Agentic RAG y construimos con éxito una aplicación Agentic RAG sencilla. Exploramos los conceptos básicos y los pasos prácticos para poner en marcha nuestra aplicación inicial utilizando el motor de consultas del enrutador. En este artículo de seguimiento, elevaremos nuestros conocimientos incorporando una potente característica: la llamada […]

The post Agentic RAG con Llama-index | Llamada a función #02 first appeared on Planeta Chatbot.

]]>
En este artículo, profundizamos en los fundamentos de Agentic RAG y construimos con éxito una aplicación Agentic RAG sencilla. Exploramos los conceptos básicos y los pasos prácticos para poner en marcha nuestra aplicación inicial utilizando el motor de consultas del enrutador. En este artículo de seguimiento, elevaremos nuestros conocimientos incorporando una potente característica: la llamada a funciones, también conocida como llamada a herramientas. Esta mejora ampliará significativamente las capacidades de nuestros agentes RAG. Así que, embarquémonos en la siguiente fase de nuestro viaje y exploremos cómo integrar la llamada a funciones en nuestras aplicaciones RAG.

Qué es una herramienta

Una herramienta es esencialmente una función Python que pasamos a los LLMs, permitiéndoles interactuar con el mundo externo. Puedes escribir una herramienta que interactúe con tu API personal, y el LLM puede entonces llamar a esta herramienta, pasando los argumentos necesarios basados en la consulta del usuario. Esto permite interacciones dinámicas y poderosas entre el LLM y sistemas externos.

Por qué la llamada a herramientas

Puede que al principio te preguntes por qué necesitamos la llamada a herramientas. Al fin y al cabo, la función principal del LLM en un sistema RAG es la síntesis. Entonces, ¿por qué necesita llamar a una función, también conocida como herramienta?

Bueno, si leíste el último artículo, ¿recuerdas cómo determinamos el mejor motor de rutas a ejecutar cuando trabajamos con el motor de consultas del enrutador? El LLM, utilizando un selector (LLMSingleSelector), fue capaz de elegir qué herramienta de motor de enrutamiento utilizar. Este es sólo un ejemplo de por qué necesitamos la llamada a herramientas.

Imagina que estamos construyendo un sistema de reservas con un LLM o queremos escribir automáticamente la salida de un pipeline RAG en un fichero usando un sistema basado en LLM. Tenemos que definir una función que se encargue de escribir el contenido en un archivo y, a continuación, pasar esta función al LLM. El LLM puede entonces determinar los argumentos necesarios para pasar al llamar a esta función. Esa función es una herramienta. Esperamos que estos ejemplos nos aclaren por qué necesitamos llamar a funciones.

Configuración e inicializaciones

Usaremos el entorno que configuramos en el último artículo. La única diferencia es que voy a crear un nuevo .ipynb que vamos a utilizar para este artículo de llamada a la herramienta.

Funciones de ejemplo para herramientas

Vamos a definir un par de funciones que podremos utilizar más adelante como herramientas. En este caso pueden ser cualquier tipo de funciones. Sólo asegúrate de tener dos cosas muy importantes en tus funciones:

  1. Anotaciones de tipo: Esto ayudará al LLM a saber qué tipo de datos o tipo de datos necesita pasar tu función o herramienta.
  2. Función do-strings: Esto le dará una descripción de la herramienta o función al LLM para que sepa para que puede ser usada la función o herramienta.

def add(x: int, y: int) -> int:
«»»Add two numbers together.»»»
return x + y

# substraction function
def sub(x: int, y: int) -> int:
«»»Substract two numbers.»»»
return x – y

# multiplication function
def mul(x: int, y: int) -> int:
«»»Multiply two numbers.»»»
return x * y

# get user information
def get_user_info(name: str) -> str:
«»»Get user information.»»»
data = {
«John Doe»: {
«age»: 30,
«location»: «USA»
},
«Jane Doe»: {
«age»: 25,
«location»: «UK»
}
}
return f’User name {name}, age is {data[name][«age»]} and location is {data[name][«location»]}’

Creando herramientas a partir de Funciones Python

Una vez que tenemos estas funciones definidas, podemos pasar a convertir estas funciones en herramientas que el LLM puede invocar. Para ello podemos utilizar el siguiente bloque de código:

from llama_index.core.tools import FunctionTool

addition_tool = FunctionTool.from_defaults(fn=add)
get_user_info_tool = FunctionTool.from_defaults(fn=get_user_info)
multiplication_tool = FunctionTool.from_defaults(fn=mul)
substraction_tool = FunctionTool.from_defaults(fn=sub)

tools = [addition_tool, get_user_info_tool, multiplication_tool, substraction_tool]

Probando la Llamada a Herramientas

Ahora que hemos conseguido convertir nuestras funciones Python en herramientas, vamos a probarlas pasándoles una consulta que requiera el uso de una de las herramientas.

from llama_index.llms.openai import OpenAI

llm = OpenAI(model=»gpt-3.5-turbo»)

response = llm.predict_and_call(
tools,
«What is the product of 4 and 5»,
verbose=True
)
print(str(response))

response = llm.predict_and_call(
tools,
«Give more the details of John Doe»,
verbose=True
)
print(str(response))

Aquí podemos ver no sólo que el LLM es capaz de saber a qué función llamar y a qué herramientas llamar, sino también qué parámetros pasar a esas funciones y herramientas llamadas.

Búsqueda vectorial con metadatos

Ya que el LLM es capaz de saber qué herramienta llamar y qué función pasar, podemos utilizar esto para pasar a la herramienta de búsqueda vectorial metadatos tales como el número de página del documento en el que queremos buscar.

Para crear la búsqueda con capacidad de filtrado de metadatos, primero necesitaremos construir una búsqueda vectorial simple, implementaremos todo lo que vimos en el primer artículo.

from llama_index.core import SimpleDirectoryReader

# load lora_paper.pdf documents
documents = SimpleDirectoryReader(input_files=[«./datasets/lora_paper.pdf»]).load_data()

from llama_index.core.node_parser import SentenceSplitter

# chunk_size of 1024 is a good default value
splitter = SentenceSplitter(chunk_size=1024)
# Create nodes from documents
nodes = splitter.get_nodes_from_documents(documents)

from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

# LLM model
Settings.llm = OpenAI(model=»gpt-3.5-turbo»)
# embedding model
Settings.embed_model = OpenAIEmbedding(model=»text-embedding-ada-002″)

from llama_index.core import VectorStoreIndex

# vector store index
vector_index = VectorStoreIndex(nodes)

Añadir capacidad de filtrado de metadatos:

from llama_index.core.vector_stores import MetadataFilters

# Create vector search query engine
query_engine = vector_index.as_query_engine(
similarity_top_k=2,
filters=MetadataFilters.from_dicts(
[
{«key»: «page_label», «value»: «2»}
]
)
)

response = query_engine.query(
«Tell me about the Problem statement as explained»,
)
print(str(response))

En el código anterior, limitamos la búsqueda únicamente a la página 2, donde se habla del planteamiento del problema en el documento de investigación. Podemos confirmar que la búsqueda sólo se realizó en la página 2 utilizando:

for n in response.source_nodes:
print(n.metadata)
print(«=============Text=============»)
print(n.get_text())
print(«=============Text=============»)

En la imagen de la ejecución del código anterior, puede ver que la búsqueda de los nodos se limita únicamente a la página número dos. También puede introducir otros metadatos.

Herramienta de recuperación automática

Ahora que somos capaces de recuperar contenido especificando otros metadatos. Una cosa que puede notar es que tuvimos que especificar manualmente el filtro de metadatos. En la mayoría de los casos, esto no es lo ideal. ¿Podemos obtener el LLM especificar en el propio filtro basado en lo que la consulta del usuario se pasó. Ejemplo:

«¿Qué se mencionó sobre el planteamiento del problema en la página 2?».

A partir de esta consulta, el LLM debería ser capaz de pasar en el filtro de metadatos el número de página como 2. Implementemos esto:

Primero implementemos la búsqueda vectorial:

from typing import List
from llama_index.core.vector_stores import FilterCondition

def vector_search_query(
query: str,
page_numbers: List[str]
) -> str:
«»»Conduct a vector search across an index using the following parameters:

query (str): This is the text string you want to embed and search for within the index.
page_numbers (List[str]): This parameter allows you to limit the search to
specific pages. If left empty, the search will encompass all pages in the index.
If page numbers are specified, the search will be filtered to only include those pages.

«»»

metadata_dicts = [
{«key»: «page_label», «value»: p} for p in page_numbers
]


query_engine = vector_index.as_query_engine(
similarity_top_k=2,
filters=MetadataFilters.from_dicts(
metadata_dicts,
condition=FilterCondition.OR
)
)
response = query_engine.query(query)
return response

vector_query_tool = FunctionTool.from_defaults(
name=»vector_search_tool»,
fn=vector_search_query
)

response = llm.predict_and_call(
[vector_query_tool],
«What was mentioned about the problem statement in page 2?»,
verbose=True
)

Ahora puede ver que la llamada a la función se realiza automáticamente pasando los metadatos correctos como página 2. El LLM fue capaz de inferir el filtro de metadatos de número de página. Hay otros filtros de metadatos que podemos utilizar, como los filtros de metadatos de pie de página.

Podemos confirmar que los datos fueron recuperados de la página 2 usando lo siguiente:

for n in response.source_nodes:
print(n.metadata)
print(«=============Text=============»)
print(n.get_text())
print(«=============Text=============»)

Ahora, incorporemos la herramienta de resumen para asegurarnos de que el enrutador es capaz de elegir la herramienta de motor de consulta correcta que debe utilizar.

from llama_index.core import SummaryIndex
from llama_index.core.tools import QueryEngineTool

summary_index = SummaryIndex(nodes)

summary_query_engine = summary_index.as_query_engine(
response_mode=»tree_summarize»,
use_async=True,
)

summary_tool = QueryEngineTool.from_defaults(
name=»summary_tool»,
query_engine=summary_query_engine,
description=(
«Useful for summarization questions related to the Lora paper.»
),
)

response = llm.predict_and_call(
[vector_search_query_tool, summary_tool],
«What was mentioned about the problem statement in page 2?»,
verbose=True
)

response = llm.predict_and_call(
[vector_search_query_tool, summary_tool],
«Give me a summary of the paper.»,
verbose=True
)

RAG

for n in response.source_nodes:
print(n.metadata)
print(«=============Text=============»)
print(n.get_text()[:10])
print(«=============Text=============»)

Conclusión

Enhorabuena por haber llegado hasta aquí. Hemos hecho una inmersión profunda en la llamada a herramientas. Hasta ahora todo lo que hemos hecho desde el primer artículo ha girado en torno a la llamada de herramientas de un solo paso donde todo se hace en un solo bucle.

Esto tiene algunas limitaciones, vamos a abordar esto en el próximo artículo cuando nos sumergimos en el bucle de razonamiento con el razonamiento de varios pasos.

Otras plataformas donde puedes ponerte en contacto conmigo:

  1. YouTube
  2. Twitter
  3. LinkedIn
  4. Discord

¡Feliz codificación! Y hasta la próxima, que el mundo sigue girando.

The post Agentic RAG con Llama-index | Llamada a función #02 first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/agentic-rag-con-llama-index-llamada-a-funcion-02/feed/ 0
Agentic RAG con Llama-index | Motor de consulta del enrutador #01 https://desa.planetachatbot.com/agentic-rag-con-llama-index-motor-de-consulta-del-enrutador-01/?utm_source=rss&utm_medium=rss&utm_campaign=agentic-rag-con-llama-index-motor-de-consulta-del-enrutador-01 https://desa.planetachatbot.com/agentic-rag-con-llama-index-motor-de-consulta-del-enrutador-01/#respond Wed, 26 Jun 2024 06:00:03 +0000 https://desa.planetachatbot.com/?p=17879 ¿Cansado de los viejos sistemas RAG (Generación Aumentada de Recuperación) que hemos tratado ampliamente en otras entradas del blog? Pues yo estoy cansado de ellos. Hagamos algo divertido para llevar las cosas al siguiente nivel. Vamos a repasar la construcción de tus propios sistemas Agentic RAG, introduciendo la idea de agentes en un flujo de […]

The post Agentic RAG con Llama-index | Motor de consulta del enrutador #01 first appeared on Planeta Chatbot.

]]>
¿Cansado de los viejos sistemas RAG (Generación Aumentada de Recuperación) que hemos tratado ampliamente en otras entradas del blog? Pues yo estoy cansado de ellos. Hagamos algo divertido para llevar las cosas al siguiente nivel. Vamos a repasar la construcción de tus propios sistemas Agentic RAG, introduciendo la idea de agentes en un flujo de trabajo de sistema RAG bien definido.

El año pasado la palabra de moda eran los sistemas RAG, este año las cosas han dado un giro, ahora todo gira en torno a los agentes. Si echas de menos la era de la palabra de moda RAG, no pasa nada porque también podemos introducir agentes en los sistemas RAG. Lo bueno es que es incluso mejor.

En este artículo, repasaremos cómo implementar una aplicación RAG Agentic básica usando Llama-index. Este es el primer artículo de una serie de artículos que publicaré en las próximas semanas sobre arquitecturas RAG Agentic.

Canal básico de generación mejorada de recuperación (RAG)

Antes de continuar, quiero refrescar un poco cómo es y cómo funciona una arquitectura RAG tradicional. Este conocimiento será útil más adelante y también para los principiantes que no sepan cómo funciona una canalización RAG básica.

De la imagen anterior de un sistema RAG sencillo, tenemos simplemente lo siguiente con lo que trabajamos:

  1. Documentos: Este es el contexto en el que quieres aumentar tu LLM con información externa que alimenta a un LLM. Puede ser un PDF o cualquier otro documento de texto o incluso imágenes para un LLM multimodal.
  2. Trozos: El documento más grande se divide en tamaños más pequeños que normalmente se llaman trozos, a veces también llamados nodos.
  3. Incrustaciones: Una vez que tenemos los trozos de menor tamaño, creamos incrustaciones vectoriales para ellos. Una vez recibida la consulta del usuario, se realiza una búsqueda de similitudes y se recuperan los documentos más parecidos. Estos fragmentos de documento recuperados se envían junto con la consulta del usuario al LLM, y los documentos recuperados actúan como contexto. A partir de ahí, el LLM genera una respuesta.

La explicación anterior es el funcionamiento típico de un sistema tradicional de RAG.

Por qué RAG Agentic

Hemos visto la implementación de una RAG simple desde arriba, este enfoque es adecuado para tareas simples de GC sobre uno o pocos documentos. No es adecuado para tareas complejas de control de calidad y resumen de grandes conjuntos de documentos.

Aquí es donde los agentes pueden entrar en juego, para ayudar a llevar la simple implementación de la RAG a otro nivel. Con los sistemas RAG agénticos, las tareas más complejas, como el resumen de documentos, el control de calidad complejo y muchas otras tareas, pueden llevarse a cabo mucho más fácilmente. Agentic RAG también le ofrece la posibilidad de incorporar llamadas a herramientas en su sistema RAG y estas herramientas pueden ser funciones personalizadas que usted mismo defina.

En esta serie de artículos, repasaremos lo siguiente:

  1. Motores de consulta de enrutadores: Esta es la forma más simple de un RAG agéntico. Esto nos da la habilidad de añadir sentencias lógicas que pueden ayudar al LLM a decidir sobre qué ruta enrutar una tarea específica dependiendo de la(s) tarea(s) que necesite(n) ser llevada(s) a cabo y del conjunto de herramientas que hayamos puesto a disposición del LLM.
  2. Llamada a Herramientas: Aquí veremos cómo añadir nuestras propias herramientas personalizadas a la arquitectura agentic RAG. Aquí implementaremos interfaces para que los agentes seleccionen una herramienta de entre un conjunto de herramientas que les proporcionaremos y luego dejaremos que el LLM proporcione los argumentos necesarios que hay que pasar para llamar a estas herramientas, ya que estas herramientas son simplemente funciones de Python, al menos las que tú mismo has definido.
  3. RAG Agentico con Capacidades de Razonamiento Multipaso
  4. RAG Agenética con Capacidades de Razonamiento Multipaso con Múltiples Documentos

Motor de consulta del enrutador

Esta es la forma más simple de RAG agentic, al menos en Llama-index. En este enfoque simplemente tenemos un motor de enrutamiento que, con la ayuda de un LLM, determina qué herramienta o motor de consulta utilizar para abordar una consulta de usuario dada.

Esta es la implementación básica de cómo funciona un motor de consulta de enrutador.

Configuración del entorno del proyecto

Para configurar tu entorno de desarrollo, crea una carpeta llamada agentic_rag, dentro de esta carpeta, crea otra carpeta llamada basics. Una vez hecho esto, navega dentro de la carpeta basics e inicializa un Python Poetry project

$ poetry init

Para empezar, asegúrate de que tienes tu clave API OpenAI lista, puedes obtener tu clave desde aquí si aún no la tienes. Una vez que tengas tu clave api lista, añádela a tu archivo .env:

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Entonces, ¿dónde está este archivo .env? Bueno, he creado una configuración env desarrollo de la siguiente manera:

Imagen de Code With Prince
Imagen de Code With Prince

Sigue esta estructura de directorios y añada sus archivos como se muestra en las imágenes anteriores.

Instalación de paquetes

Usaremos Llama-index para esto. Vamos a instalarlo junto con otras librerías que utilizaremos:

$ poetry add python-dotenv ipykernel llama-index nest_asyncio

Descarga del conjunto de datos

Necesitaremos un archivo PDF para experimentar. Puedes descargar este PDF desde aquí. De nuevo, siéntete libre de utilizar cualquier archivo PDF de su agrado.

Cargar y escupir el documento en los nodos

Ahora estamos listos para empezar, primero vamos a cargar nuestras variables de entorno utilizando la biblioteca python-dotenv que acabamos de instalar:

import dotenv
%load_ext dotenv
%dotenv

También usaremos la biblioteca nest-asyncio ya que Llama-index usa muchas funciones asyncio en segundo plano:

import nest_asyncio
nest_asyncio.apply()

Ahora, carguemos nuestros datos:

from llama_index.core import SimpleDirectoryReader

# load lora_paper.pdf documents
documents = SimpleDirectoryReader(input_files=[«./datasets/lora_paper.pdf»]).load_data()

Crear fragmentos de documentos

Una vez que hayamos cargado los datos correctamente, avancemos para dividir el documento más grande en fragmentos de 1024 tamaños de fragmentos:

from llama_index.core.node_parser import SentenceSplitter

# chunk_size of 1024 is a good default value
splitter = SentenceSplitter(chunk_size=1024)
# Create nodes from documents
nodes = splitter.get_nodes_from_documents(documents)

Podemos obtener más información sobre cada uno de estos nodos usando:

node_metadata = nodes[1].get_content(metadata_mode=True)
print(node_metadata)

Imagen por código con Prince

Creación de LLM e incorporación de modelos

Usaremos el modelo OpenAI gpt-3.5-turbo como LLM y el modelo de incrustación text-embedding-ada-002 para crear las incrustaciones.

from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

# LLM model
Settings.llm = OpenAI(model=»gpt-3.5-turbo»)
# embedding model
Settings.embed_model = OpenAIEmbedding(model=»text-embedding-ada-002″)

Creando índices

Como se muestra en las imágenes anteriores, tendremos dos índices principales que usaremos:

  1. Índice resumido: obtuve esta explicación de los documentos oficiales de Llamaindex:

El índice resumido es una estructura de datos simple donde los nodos se almacenan en una secuencia. Durante la construcción del índice, los textos del documento se fragmentan, se convierten en nodos y se almacenan en una lista.

Durante el tiempo de consulta, el índice de resumen recorre los nodos con algunos parámetros de filtro opcionales y sintetiza una respuesta de todos los nodos.

  1. Índice vectorial: este es solo un almacén de índice normal creado a partir de incrustaciones de palabras desde el cual podemos realizar búsquedas de similitud para obtener el n índice más similar.

Podemos usar el siguiente código para crear estos dos índices:

from llama_index.core import SummaryIndex, VectorStoreIndex

# summary index
summary_index = SummaryIndex(nodes)
# vector store index
vector_index = VectorStoreIndex(nodes)

Convertir índices vectoriales en motores de consulta

Una vez que tengamos los índices vectoriales creados y almacenados, tendremos que continuar con la creación de los motores de consulta que convertiremos en herramientas, también conocidas como herramientas de consulta, que nuestros agentes podrán usar más adelante.

# summary query engine
summary_query_engine = summary_index.as_query_engine(
response_mode=»tree_summarize»,
use_async=True,

)

# vector query engine
vector_query_engine = vector_index.as_query_engine()

En el caso anterior, tenemos dos motores de consulta diferentes. Colocaremos cada uno de estos motores de consulta debajo de un motor de consulta de enrutador que luego decidirá a qué motor de consulta enrutar según la consulta del usuario.

En el código anterior, especificamos el parámetro use_async para realizar consultas más rápidas; esta es una de las razones por las que también tuvimos que usar la biblioteca next_asyncio.

Herramientas de consulta

Una herramienta de consulta es simplemente un motor de consulta con metadatos, específicamente una descripción de para qué se puede utilizar o para qué sirve la herramienta de consulta. Esto ayuda al motor de consultas del enrutador a poder decidir a qué herramienta del motor de consultas enrutar dependiendo de la consulta que recibe.

from llama_index.core.tools import QueryEngineTool

summary_tool = QueryEngineTool.from_defaults(
query_engine=summary_query_engine,
description=(
«Useful for summarization questions related to the Lora paper.»
),
)

vector_tool = QueryEngineTool.from_defaults(
query_engine=vector_query_engine,
description=(
«Useful for retrieving specific context from the the Lora paper.»
),
)

Motor de consulta de enrutador

Finalmente, podemos continuar con la creación de la herramienta del motor de consulta del enrutador. Esto nos permitirá utilizar todas las herramientas de consulta que creamos a partir de los motores de consulta que definimos anteriormente, específicamente summary_tool y vector_tool.

from llama_index.core.query_engine.router_query_engine import RouterQueryEngine
from llama_index.core.selectors import LLMSingleSelector

query_engine = RouterQueryEngine(
selector=LLMSingleSelector.from_defaults(),
query_engine_tools=[
summary_tool,
vector_tool,
],
verbose=True
)

LLMSingleSelector: este es un selector que utiliza LLM para seleccionar una única opción de una lista de opciones. Puedes leer más al respecto desde aquí.

Probando el motor de consulta del enrutador

Sigamos adelante y usemos el siguiente código para probar el motor de consulta del enrutador:

response = query_engine.query(«What is the summary of the document?»)
print(str(response))

Arriba está el resumen del artículo que se resume en todo el contexto en el documento Lora dado que pasamos al motor de consulta de resumen.

Dado que estamos utilizando el índice de resumen que almacena todos los nodos en una lista secuencial, se visitan todos los nodos y se genera un resumen general de todos los nodos para obtener el resumen final.

Puedes confirmar esto comprobando la longitud de la respuesta, el atributo source_nodes nos devuelve las fuentes utilizadas para generar el resumen.

print(len(response.source_nodes))

Puedes notar que el número 38 es el mismo que el número de nodos que obtuvimos después de realizar la fragmentación del documento. Esto significa que todos los nodos fragmentados se han utilizado para generar el resumen.

Hagamos otra pregunta que no implique el uso de la herramienta de resumen.

response = query_engine.query(«What is the long from of Lora?»)
print(str(response))

Esto utiliza la herramienta de índice de vectores; sin embargo, la respuesta no es tan precisa.

Poniendolo todo junto

Ahora que hemos entendido esta canalización básica, avancemos para convertirla en una función de canalización que llamaremos utilizar más adelante.

async def create_router_query_engine(
document_fp: str,
verbose: bool = True,
) -> RouterQueryEngine:
# load lora_paper.pdf documents
documents = SimpleDirectoryReader(input_files=[document_fp]).load_data()


# chunk_size of 1024 is a good default value
splitter = SentenceSplitter(chunk_size=1024)
# Create nodes from documents
nodes = splitter.get_nodes_from_documents(documents)


# LLM model
Settings.llm = OpenAI(model=»gpt-3.5-turbo»)
# embedding model
Settings.embed_model = OpenAIEmbedding(model=»text-embedding-ada-002″)


# summary index
summary_index = SummaryIndex(nodes)
# vector store index
vector_index = VectorStoreIndex(nodes)


# summary query engine
summary_query_engine = summary_index.as_query_engine(
response_mode=»tree_summarize»,
use_async=True,
)

# vector query engine
vector_query_engine = vector_index.as_query_engine()


summary_tool = QueryEngineTool.from_defaults(
query_engine=summary_query_engine,
description=(
«Useful for summarization questions related to the Lora paper.»
),
)

vector_tool = QueryEngineTool.from_defaults(
query_engine=vector_query_engine,
description=(
«Useful for retrieving specific context from the the Lora paper.»
),
)



query_engine = RouterQueryEngine(
selector=LLMSingleSelector.from_defaults(),
query_engine_tools=[
summary_tool,
vector_tool,
],
verbose=verbose
)



return query_engine

Entonces podemos llamar a esta función de la siguiente manera:

query_engine = await create_router_query_engine(«./datasets/lora_paper.pdf»)
response = query_engine.query(«What is the summary of the document?»)
print(str(response))

Sigamos adelante y creemos un archivo utils.py y tengamos lo siguiente dentro de él:

from llama_index.core.query_engine.router_query_engine import RouterQueryEngine
from llama_index.core.selectors import LLMSingleSelector
from llama_index.core.tools import QueryEngineTool
from llama_index.core import SummaryIndex, VectorStoreIndex
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core import SimpleDirectoryReader

async def create_router_query_engine(
document_fp: str,
verbose: bool = True,
) -> RouterQueryEngine:
# load lora_paper.pdf documents
documents = SimpleDirectoryReader(input_files=[document_fp]).load_data()


# chunk_size of 1024 is a good default value
splitter = SentenceSplitter(chunk_size=1024)
# Create nodes from documents
nodes = splitter.get_nodes_from_documents(documents)


# LLM model
Settings.llm = OpenAI(model=»gpt-3.5-turbo»)
# embedding model
Settings.embed_model = OpenAIEmbedding(model=»text-embedding-ada-002″)


# summary index
summary_index = SummaryIndex(nodes)
# vector store index
vector_index = VectorStoreIndex(nodes)


# summary query engine
summary_query_engine = summary_index.as_query_engine(
response_mode=»tree_summarize»,
use_async=True,
)

# vector query engine
vector_query_engine = vector_index.as_query_engine()


summary_tool = QueryEngineTool.from_defaults(
query_engine=summary_query_engine,
description=(
«Useful for summarization questions related to the Lora paper.»
),
)

vector_tool = QueryEngineTool.from_defaults(
query_engine=vector_query_engine,
description=(
«Useful for retrieving specific context from the the Lora paper.»
),
)



query_engine = RouterQueryEngine(
selector=LLMSingleSelector.from_defaults(),
query_engine_tools=[
summary_tool,
vector_tool,
],
verbose=verbose
)



return query_engine

Luego podremos utilizar esta llamada de función desde este archivo más adelante:

from utils import create_router_query_engine

query_engine = await create_router_query_engine(«./datasets/lora_paper.pdf»)
response = query_engine.query(«What is the summary of the document?»)
print(str(response))

RAG

Conclusión

Felicitaciones por llegar hasta aquí. Eso es todo lo que cubriremos en este artículo; en el próximo artículo, veremos cómo usar una llamada de herramienta, también conocida como llamada de función.

Otras plataformas donde puedes comunicarte conmigo:

  1. YouTube
  2. Twitter
  3. LinkedIn
  4. Discord

¡Feliz codificación! Y hasta la próxima, el mundo sigue girando.

Referencias

  1. Llamaindex Summary Index
  2. Llamaindex Vector Store
  3. LLMSingleSelector Llamaindex

The post Agentic RAG con Llama-index | Motor de consulta del enrutador #01 first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/agentic-rag-con-llama-index-motor-de-consulta-del-enrutador-01/feed/ 0
Chatbot basado en LLM para el análisis avanzado de datos con Redash https://desa.planetachatbot.com/chatbot-basado-en-llm-para-analisis-avanzado-de-datos-con-redash/?utm_source=rss&utm_medium=rss&utm_campaign=chatbot-basado-en-llm-para-analisis-avanzado-de-datos-con-redash https://desa.planetachatbot.com/chatbot-basado-en-llm-para-analisis-avanzado-de-datos-con-redash/#respond Thu, 13 Jun 2024 06:00:23 +0000 https://desa.planetachatbot.com/?p=17830 Transformación del BI con nuestro complemento Redash En el panorama en constante evolución de la inteligencia empresarial, la necesidad de capacidades avanzadas de análisis de datos se ha hecho más evidente que nunca. Reconociendo este imperativo, nuestra empresa se está embarcando en un emocionante viaje para revolucionar el análisis de datos a través del desarrollo […]

The post Chatbot basado en LLM para el análisis avanzado de datos con Redash first appeared on Planeta Chatbot.

]]>
Transformación del BI con nuestro complemento Redash

En el panorama en constante evolución de la inteligencia empresarial, la necesidad de capacidades avanzadas de análisis de datos se ha hecho más evidente que nunca. Reconociendo este imperativo, nuestra empresa se está embarcando en un emocionante viaje para revolucionar el análisis de datos a través del desarrollo de un innovador chatbot con Redash.

Nuestra visión va más allá de las plataformas de BI tradicionales, con el objetivo de crear una integración perfecta que no sólo mejore la experiencia del frontend, sino que también introduzca un backend inteligente capaz de traducir las consultas de los usuarios en perspectivas procesables. Este proyecto multifacético abarca la generación de resúmenes para visualizaciones en cuadros de mando existentes, perspectivas derivadas de consultas SQL actuales y la creación automática de consultas SQL, visualizaciones y cuadros de mando Redash completos.

El núcleo de esta innovación es el puente que estamos construyendo entre el lenguaje natural y las consultas SQL complejas. Nuestro objetivo es democratizar el análisis de datos, haciéndolo accesible a los miembros del equipo con conocimientos no técnicos. Al facilitar una conexión fluida entre los usuarios y sus datos, aspiramos a agilizar los procesos analíticos, fomentando la eficiencia, la facilidad de uso y, en última instancia, la toma de decisiones estratégicas fundamentadas.

Acompáñanos en este viaje transformador mientras desvelamos una herramienta que no sólo simplifica la exploración de datos, sino que también allana el camino para una nueva era de análisis de datos accesibles y potentes.

Entender la analítica de datos

Antes de profundizar en los entresijos de los Grandes Modelos del Lenguaje (LLM) y su papel en la analítica, vamos a establecer una comprensión clara de lo que implica la analítica de datos y las tareas que realizan los analistas.

En el núcleo de nuestra misión analítica se encuentra el compromiso de ayudar a los equipos de producto a tomar decisiones informadas basadas en los datos disponibles en un plazo determinado. Para precisar aún más el ámbito de actuación de los analistas impulsados por LLM, recurrimos al exhaustivo marco propuesto por Gartner, que identifica cuatro técnicas distintas de Análisis y Datos.

  1. Análisis descriptivo: Esta técnica aborda la pregunta «¿Qué ha pasado?». Implica tareas de elaboración de informes y trabajar con herramientas de Business Intelligence (BI) para, por ejemplo, determinar los ingresos en un mes concreto.
  2. Análisis de diagnóstico: Más allá del análisis descriptivo, esta técnica busca respuestas a preguntas como «¿Por qué ha ocurrido algo?». Los analistas que se dedican al análisis de diagnóstico profundizan en el análisis detallado de los datos, empleando técnicas de desglose y troceado. Por ejemplo, pueden investigar por qué los ingresos disminuyeron un 10% en comparación con el año anterior.
  3. Análisis predictivo: Esta técnica proporciona información sobre el futuro, respondiendo a preguntas como «¿Qué ocurrirá?». La previsión y la simulación son las piedras angulares del análisis predictivo, ya que permiten a las empresas anticipar resultados en distintos escenarios.
  4. Análisis prescriptivo: Al dar forma a las decisiones finales, la analítica prescriptiva aborda cuestiones como «¿En qué debemos centrarnos?» o «¿Cómo podríamos aumentar el volumen en un 10%?». Esta técnica orienta la toma de decisiones estratégicas basándose en los datos analizados.

Las empresas suelen pasar por estas etapas analíticas de forma secuencial, lo que refleja su madurez en materia de datos. Del mismo modo, los analistas evolucionan de niveles junior a senior, atravesando estas etapas desde tareas de elaboración de informes bien definidas hasta la resolución de consultas estratégicas complejas.

En el contexto de los analistas impulsados por LLM, nuestro enfoque inicial se centra en el análisis descriptivo y las tareas de elaboración de informes. El dominio de estos fundamentos es crucial antes de profundizar en el análisis predictivo y prescriptivo. Este enfoque estratégico se alinea con la progresión natural tanto de las empresas como de los analistas individuales, garantizando una base sólida para las tareas analíticas avanzadas.

LLM y análisis de datos

Los Grandes Modelos del Lenguaje (LLM) son modelos avanzados de inteligencia artificial diseñados para comprender y generar texto similar al humano a partir de extensos conjuntos de datos de entrenamiento lingüístico. En el ámbito del análisis de datos, los LLM desempeñan un papel fundamental al salvar la distancia entre las consultas complejas y el lenguaje natural.

Estos modelos son fundamentales para mejorar el análisis descriptivo y las tareas de elaboración de informes, ya que permiten a los analistas extraer información significativa de los datos mediante interacciones intuitivas y basadas en el lenguaje. Al aprovechar los LLM, los analistas de datos pueden agilizar su flujo de trabajo, empezando por las tareas básicas y avanzando gradualmente hacia retos analíticos más sofisticados. Esta integración de los LLM en el análisis de datos supone un cambio de paradigma, ya que hace que la analítica sea más accesible, eficiente y fácil de usar, lo que en última instancia permite a las organizaciones tomar decisiones bien fundadas basadas en sus datos.

¿Qué es Redash?

Redash está diseñado para permitir a cualquier persona, independientemente de su nivel de sofisticación técnica, aprovechar el poder de los datos grandes y pequeños. Los usuarios de SQL aprovechan Redash para explorar, consultar, visualizar y compartir datos de cualquier fuente de datos. Su trabajo, a su vez, permite a cualquier persona de su organización utilizar los datos. Cada día, millones de usuarios en miles de organizaciones de todo el mundo utilizan Redash para desarrollar ideas y tomar decisiones basadas en datos. Aquí destacamos algunas de las características de Redash:

  1. Basado en el navegador: Todo en tu navegador, con una URL que puedes compartir.
  2. Facilidad de uso: Sea inmediatamente productivo con los datos sin necesidad de dominar complejos programas informáticos.
  3. Editor de consultas: Compon rápidamente consultas SQL y NoSQL con un navegador de esquemas y autocompletado.
  4. Visualización y cuadros de mando: Crea hermosas visualizaciones con arrastrar y soltar, y combínelas en un único cuadro de mando.
  5. Compartición: Colabora fácilmente compartiendo visualizaciones y sus consultas asociadas, lo que permite la revisión por pares de informes y consultas.
  6. Programar actualizaciones: Actualiza automáticamente sus gráficos y cuadros de mando a intervalos regulares definidos por ti.
  7. Alertas: Define condiciones y recibe alertas instantáneas cuando cambien sus datos.
  8. API REST: Todo lo que se puede hacer en la interfaz de usuario también está disponible a través de la API REST.
  9. Amplia compatibilidad con fuentes de datos: API de fuentes de datos extensible con soporte nativo para una larga lista de bases de datos y plataformas comunes.

Plano del proyecto

Fundamentos, familiarización con las herramientas y mejora de la NLP

Objetivo: Establecer las capacidades básicas del chatbot y mejorar la PNL para obtener traducciones SQL precisas a la vez que se adquiere un profundo conocimiento de los principales desarrollos y herramientas de LLM.

Implementación:

  • Utilizar Python, OpenAI API y LangChain para la comprensión inicial del lenguaje y la traducción SQL.
  • Familiarizarse con las herramientas de OpenAI, los componentes de LangChain, LLamaIndex y las bases de datos vectoriales.
  • Revisar los enlaces relevantes y resumir los hallazgos en un informe exhaustivo.
  • Integrar LangChain en el backend Python para NLP avanzado, reemplazando el uso básico de la API OpenAI.

2. Tratamiento avanzado de datos y búsqueda semántica

Objetivo: Optimizar la gestión de datos para una recuperación y procesamiento eficientes, incorporando capacidades de búsqueda semántica mediante Bases de Datos Vectoriales.

Implantación:

  • Implementar LLamaIndex para agilizar el acceso a los datos e integrar diversas fuentes de datos.
  • Utilizar bases de datos vectoriales para almacenar y buscar texto transcrito, comentarios y metadatos de YouTube.
  • Explorar la incrustación de documentos y la búsqueda semántica mediante similitud vectorial.

3. Comprensión de las herramientas, integración de Redash y desarrollo de cuadros de mando

Objetivo: Comprender las capacidades de Redash, conectarse a las fuentes de datos y desarrollar una interfaz de panel de control fácil de usar.

Implementación:

  • Aprender Redash para visualización de datos y analítica.
  • Diseñar un esquema de datos de YouTube eficiente teniendo en cuenta el rendimiento del canal, la base de usuarios y los gastos de vídeo.
  • Esbozar la arquitectura para el complemento Redash y los sistemas backend.
  • Desarrollar la interfaz del panel de control con React para una experiencia fácil de usar.
  • Desarrollar un sistema backend para el almacenamiento y procesamiento de datos utilizando Quart (versión asíncrona de Flask).

4. Integración de LLM y generación automática de cuadros de mando

Objetivo: Integrar modelos lingüísticos para la comprensión del lenguaje natural y automatizar la generación de visualizaciones en función de las consultas de los usuarios.

Implementación:

  • Incorporar modelos lingüísticos para interpretar y procesar consultas en lenguaje natural.
  • Integrar el complemento para convertir las consultas de lenguaje natural en SQL, garantizando la compatibilidad con Redash.
  • Implementar OpenAI Actions (antes llamados Plugins) para una integración perfecta.
  • Experimentar rápidamente utilizando Flowise AI para realizar pruebas y mejoras rápidas.
  • Implementar la generación automática de visualizaciones basadas en las consultas del usuario y el contexto existente.

Este plan consolidado proporciona un enfoque coherente y sin fisuras para desarrollar un sistema de chatbot avanzado, integrando modelos lingüísticos, tratamiento de datos, búsqueda semántica y visualización fácil de usar.

Metodología

Colaboración sin fisuras

Para nuestro proyecto de equipo colaborativo, dimos el paso esencial de crear una organización GitHub para agilizar nuestros esfuerzos de colaboración y control de versiones. Dentro de esta organización, establecimos un repositorio compartido para facilitar el trabajo en equipo y la gestión del código.

Para apoyar nuestras necesidades de almacenamiento de datos y garantizar una base de datos centralizada y accesible para todo el equipo, optamos por una base de datos PostgreSQL alojada en Render. Esta decisión nos permite disponer de una infraestructura de base de datos compartida y escalable, mejorando la colaboración y la coherencia de los datos en todo el equipo. La plataforma Render proporciona un entorno fiable para nuestra base de datos PostgreSQL, en línea con la naturaleza colaborativa de nuestro proyecto y los requisitos de gestión de datos.

Creación de la máquina virtual

El inicio del proyecto comenzó con la creación de una máquina virtual dedicada, un componente crucial para lograr una configuración lista para la producción a través de la Dockerización integral. Utilizando la robusta plataforma de virtualización Proxmox dentro del laboratorio doméstico, se configuró una máquina virtual con recursos sustanciales: 4 zócalos de CPU, 4 GB de RAM y un disco duro de gran capacidad de 64 GB. Esta cuidadosa asignación garantiza un rendimiento y una escalabilidad óptimos, y constituye la base de un entorno Dockerizado sin fisuras. Tras la configuración de la máquina virtual, se instaló Debian 12 (Bookworm) como sistema operativo, proporcionando una base sólida para las fases posteriores en el desarrollo y despliegue de este emocionante proyecto.

Configuración del desarrollo local de Redash

Embarcate en el desarrollo de Redash abre un mundo de posibilidades, y el primer paso crucial es establecer un entorno local robusto. Ya sea en Linux o Windows WSL2, el proceso implica la instalación de paquetes esenciales para Docker, NodeJS y Yarn. Con el código fuente de Redash clonado, las dependencias instaladas y las variables de entorno locales generadas, los desarrolladores compilan sin problemas el front-end y construyen una imagen Docker local de Redash. Iniciar Redash localmente se convierte en algo sencillo, y acceder a la interfaz web en http://localhost:5001 marca la puerta de entrada a la configuración. La configuración de Python para el desarrollo del backend sigue el mismo camino, garantizando la compatibilidad con diversas fuentes de datos. Esta visión holística prepara el terreno para un viaje de desarrollo de Redash sin problemas. Para conocer los pasos detallados, consulta la guía completa aquí.

Conjunto de datos

Los datos de nuestro canal de YouTube son un tesoro, ya que incluyen metadatos de vídeo como títulos y fechas de carga, series temporales de metadatos de audiencia que revelan tendencias de rendimiento y comentarios con fecha y hora que fomentan el análisis de la participación de la comunidad. El texto transcrito ayuda al análisis de contenidos y al SEO, mientras que la instantánea de datos ofrece métricas en tiempo real para el perfeccionamiento estratégico y la mejora de la participación de la audiencia.

Dentro de cada carpeta de nuestras diversas fuentes de datos, un trío de archivos CSV actúa como puerta de entrada a profundos conocimientos de nuestro ecosistema de YouTube. Ya se trate de las plataformas del servicio Compartir, los datos demográficos sobre la edad de los espectadores o la distribución geográfica en Ciudades, cada fuente contribuye a la narrativa de nuestros contenidos. El estado de suscripción y los espectadores nuevos y recurrentes revelan el compromiso y la retención de la audiencia, mientras que la geografía desvela nuestra audiencia global.

El tipo de dispositivo y el sistema operativo profundizan en el panorama técnico, y el género de los espectadores enriquece la demografía de la audiencia. Los subtítulos y la CC mejoran la inclusividad, el tipo de contenido clasifica los géneros, la fuente de suscripción descubre los orígenes de los abonados y la fuente de tráfico identifica los canales de descubrimiento. Los espectadores por fecha añaden una dimensión temporal, completando un mosaico exhaustivo de nuestra presencia en YouTube con la información contenida en tres archivos CSV dentro de cada carpeta.

Creación de un esquema de base de datos para cargar datos

Para consolidar y organizar nuestros análisis de YouTube, diseñamos un esquema de base de datos estructurado. Dentro de cada archivo CSV de cada carpeta, se empleó una columna de bloqueo única para sincronizar y fusionar los datos a la perfección. Aprovechando este enfoque, facilitamos una integración cohesiva de las perspectivas. A continuación, los datos se introdujeron sistemáticamente en la base de datos, con la nomenclatura de cada carpeta como nombre distintivo de la tabla. Este meticuloso diseño del esquema agilizó el proceso de fusión, garantizando un repositorio unificado y accesible para nuestros completos análisis de YouTube.

Añadir el chatbot a redash

En la intrincada construcción del chatbot de Redash, se dedicó atención tanto a los componentes frontend como backend. A partir del robusto código fuente de Redash, el frontend se elaboró meticulosamente con React.js, lo que permitió crear componentes dinámicos y con capacidad de respuesta. Como complemento, el estilo se perfeccionó con Less CSS, añadiendo una capa extra de sofisticación a la interfaz de usuario.

En el backend, se eligió el framework Flask por su versatilidad y fiabilidad. Esta elección proporcionó una base sólida para manejar las complejidades de la funcionalidad del chatbot, garantizando la ejecución sin problemas de operaciones complejas. La interacción crítica entre el frontend y el backend se facilitó meticulosamente mediante la integración de Axios, un potente cliente HTTP, para permitir una comunicación y un intercambio de datos eficientes.

Flask se une a OpenAI GPT-3.5 Turbo

Embarcado en un viaje para infundir inteligencia en las interacciones con bases de datos, recientemente logré una integración perfecta de Flask y GPT-3.5 Turbo de OpenAI. Esta fusión ofrece un asistente dinámico capaz no sólo de analizar bases de datos PostgreSQL, sino también de generar consultas SQL sobre la marcha. He aquí una instantánea de esta integración transformadora:

Conectando los puntos: Flask y esquema de base de datos

Flask toma protagonismo estableciendo una conexión segura con una base de datos PostgreSQL. Esto no sólo garantiza una base sólida para la interacción con la base de datos, sino que también incluye un mecanismo inteligente de recuperación de esquemas, obteniendo nombres de tablas y columnas para una comprensión completa.

Magia OpenAI: GPT-3.5 Turbo desatado

Introduce el GPT-3.5 Turbo de OpenAI, perfectamente entretejido en la aplicación Flask. Con claves API seguras, este modelo se convierte en el cerebro de las conversaciones dinámicas, respondiendo de forma inteligente a las consultas de los usuarios y generando consultas SQL basadas en información contextual.

Consultas SQL basadas en chat: Las conversaciones dan forma al código

Las consultas de los usuarios desencadenan un baile de conversaciones con el modelo GPT, que da lugar a la generación inteligente de consultas SQL. El asistente no sólo interpreta las consultas de los usuarios, sino que elabora la sintaxis SQL de forma dinámica, ofreciendo respuestas contextuales que van más allá de la mera automatización.

Consultas de Redash sobre la marcha: Creación de inteligencia

La clase ChatResource se encarga de elaborar consultas Redash de forma dinámica y eficaz. Esto permite al asistente generar consultas con opciones específicas, respondiendo en tiempo real a las necesidades del usuario.

Diseñar para la resiliencia: Robustez en acción

Para garantizar un sistema fiable y resistente, la gestión robusta de errores se convierte en el centro de atención. Aprovechando el mecanismo de reintento de tenacity, la aplicación está preparada para gestionar con elegancia posibles contratiempos de la API o la base de datos.

Redash y React Client API para cuadros de mando automatizados y generación SQL

En el ámbito de la toma de decisiones basada en datos, la fusión de Redash y una sólida API de cliente de React abre una puerta a la creación de cuadros de mando sin esfuerzo y a la generación de consultas SQL dinámicas. Exploremos cómo esta potente integración puede redefinir sus flujos de trabajo de visualización de datos.

El RedashAPIClient

En el corazón de esta sinergia se encuentra el RedashAPIClient. Con su clave API y el host Redash, este cliente se convierte en su conducto para la comunicación sin fisuras, preparando el escenario para una gran cantidad de acciones.

redash_client = RedashAPIClient(api_key=”your_api_key”, host=”http://localhost:5000″)
Creating Intelligent Data Sources:

Creación de fuentes de datos inteligentes

Genera fuentes de datos sin esfuerzo con el método create_data_source. Define el tipo, el nombre y las opciones adicionales para adaptar la fuente a sus requisitos exclusivos.

redash_client.create_data_source(_type=”your_type”, name=”your_data_source_name”, options={“your_option”: “option_value”})

Consulta y actualización dinámicas

Interactúa dinámicamente con tus consultas. Activa una actualización de consulta o genera resultados de consulta sobre la marcha utilizando los métodos refresh_query y generate_query_results.

redash_client.refresh_query(qry_id=your_query_id)
redash_client.generate_query_results(ds_id=your_data_source_id, qry=”your_query_string”)

Visualizaciones elevadas

Potencia tus cuadros de mando con gráficos y tablas visualmente atractivos. El método create_visualization admite diversos tipos de visualización, desde gráficos de líneas hasta tablas dinámicas.

redash_client.create_visualization(qry_id=your_query_id, _type=”your_visualization_type”, name=”your_visualization_name”, columns=[…], x_axis=”your_x_axis”, y_axis=[…], size_column=”your_size_column”, group_by=”your_group_by”, custom_options={“your_custom_option”: “option_value”}, desc=”your_description”)

Agilización de la gestión de cuadros de mando

Simplifica la creación de cuadros de mando y la adición de widgets con los métodos create_dashboard, add_widget y calculate_widget_position. Ajusta la apariencia de su panel de control y publícalo sin esfuerzo.

redash_client.create_dashboard(name=”your_dashboard_name”)
redash_client.add_widget(db_id=your_dashboard_id, text=”your_widget_text”, vs_id=your_visualization_id, full_width=True, position={“your_position_option”: “option_value”})
redash_client.calculate_widget_position(db_id=your_dashboard_id, full_width=True)
redash_client.publish_dashboard(db_id=your_dashboard_id)

Esta integración de Redash y React Client API redefine el panorama de la visualización de datos y la generación de consultas. Desde la creación de fuentes de datos inteligentes hasta la elaboración de cuadros de mando dinámicos, este dúo de API simplifica el proceso, ofreciendo una potente herramienta tanto para desarrolladores como para entusiastas de los datos.

Redash

Desafíos

Embárcate en el viaje para construir un chatbot integrado en Redash trajo consigo una serie de retos que pusieron a prueba las habilidades y la resistencia de nuestro equipo. En esta entrada del blog, vamos a profundizar en los tres principales desafíos encontrados durante el proceso de desarrollo, con un enfoque particular en el uso del cliente RedashAPI para crear fuentes de datos, consultas y cuadros de mando.

Despliegue local e integración

El obstáculo inicial fue la necesidad de construir Redash localmente e integrarlo a la perfección con nuestro chatbot. Esto exigió un enfoque meticuloso para garantizar una fusión perfecta de los dos componentes. Era primordial superar los problemas de compatibilidad y garantizar una experiencia de usuario fluida. Con el reto añadido de utilizar el cliente RedashAPI para establecer conexiones, crear fuentes de datos e integrarlas de forma eficaz, nuestro equipo navegó a través de esta complejidad, demostrando nuestra capacidad para aprovechar potentes herramientas para una solución cohesionada.

Diseño robusto del esquema de la base de datos

El diseño de un esquema de base de datos capaz de acomodar diversos conjuntos de datos sin comprometer los valores y las relaciones supuso el segundo gran reto. Lograr un equilibrio entre el almacenamiento exhaustivo de los datos y el mantenimiento de la integridad exigía un enfoque reflexivo y estratégico. Nuestro equipo no sólo abordó este reto aprovechando el cliente RedashAPI para crear consultas que interactuaran eficazmente con la base de datos, sino que también las integró a la perfección en nuestro chatbot, garantizando una experiencia de usuario dinámica y receptiva.

Integración de la API de OpenAI

El tercer reto consistió en integrar la API de OpenAI en un plazo limitado. Comprender los entresijos de la API e implementarla con eficacia exigía una comprensión rápida y una ejecución precisa. Comprender las capacidades de OpenAI y aplicarlas con la metodología adecuada fueron cruciales para el éxito de nuestro proyecto. El uso del cliente RedashAPI para crear cuadros de mando mejoró aún más nuestra capacidad de visualizar e interpretar los datos de OpenAI, añadiendo una capa adicional de complejidad que superamos con éxito.

Conclusión

En el ámbito del desarrollo de un chatbot integrado en Redash, los retos son inevitables. Sin embargo, es a través de la superación de estos desafíos que la verdadera innovación y el progreso emergen. Nuestro viaje estuvo marcado por la resolución de desafíos de forma exitosa, incluida la utilización eficaz del cliente RedashAPI para crear fuentes de datos, consultas y cuadros de mando. Cada obstáculo fue una oportunidad para aprender, crecer y, en última instancia, ofrecer un producto sofisticado y funcional. Al reflexionar sobre nuestras experiencias, recordamos que el camino hacia la innovación suele estar pavimentado de retos que, cuando se afrontan de frente, conducen al éxito y al logro.

Lecciones aprendidas

La adaptabilidad es clave

El viaje reforzó la importancia de la adaptabilidad frente a retos imprevistos. Nuestra capacidad para pivotar, reevaluar y adaptar nuestras estrategias fue crucial para superar los obstáculos y garantizar que mantuviéramos el rumbo a pesar de los giros inesperados en el proceso de desarrollo.

Resolución de problemas en colaboración

Los retos se afrontan mejor en equipo. La colaboración en la resolución de problemas no sólo aporta diversas perspectivas, sino que también fomenta una cultura de responsabilidad compartida. Nuestro éxito en la resolución de problemas complejos fue testimonio de la fuerza de la inteligencia colectiva de nuestro equipo.

La planificación estratégica mitiga los riesgos

Aunque los retos son inevitables, la planificación estratégica y la previsión pueden mitigar los riesgos potenciales. Identificar y abordar de forma proactiva los posibles obstáculos nos permitió navegar por el proceso de desarrollo con mayor fluidez, reduciendo el impacto de los retos imprevistos.

Limitaciones

Escalabilidad

El proyecto puede enfrentarse a problemas de escalabilidad, especialmente cuando se trata de un gran volumen de peticiones simultáneas de usuarios. A medida que crezca la base de usuarios, el sistema podría experimentar problemas de rendimiento, por lo que la optimización de la escalabilidad sería una consideración crítica.

Compatibilidad con diversas fuentes de datos

Garantizar la compatibilidad con una amplia gama de fuentes de datos es complejo. Los futuros desarrollos deberán tener en cuenta los problemas relacionados con la integración de fuentes de datos, garantizando una interacción fluida con diversas bases de datos y plataformas.

Historial específico

Es posible que la aplicación actual carezca de una función sólida para guardar el historial de cada consulta o sesión de chat. A los usuarios les puede resultar difícil volver a consultar o hacer referencia a interacciones específicas dentro de una sesión, lo que limita su capacidad para seguir la evolución de las consultas o las percepciones durante una conversación.

Plan a futuro

Registro del historial específico para cada pregunta

Implementar un mecanismo de guardado del historial dentro de las prompts o sesiones de chat sería crucial. Esta función permitiría a los usuarios revisar y navegar por el historial de sus interacciones, proporcionando una visión contextual de la conversación. Los usuarios deberían poder consultar preguntas, consultas y respuestas anteriores dentro de la misma sesión.

Historial consultable

Mejore la función de guardado del historial haciéndola consultable. Los usuarios deben tener la capacidad de buscar términos específicos o palabras clave dentro del historial específico de la consulta, facilitando el acceso rápido a las partes relevantes de la conversación.

Integración del machine learning

Integrar algoritmos de machine learning que permitan al sistema aprender de las interacciones y comentarios de los usuarios. Esto podría mejorar la capacidad del sistema para adaptarse a las preferencias del usuario y proporcionar información más personalizada a lo largo del tiempo.


Visita mi web personal para saber más sobre lo que hago www.abelbekele.com

Sígueme en GitHub: AbelBekele

Sígueme en Medium: Abel Bekele

Conectémonos en LinkedIn: Abel Bekele

The post Chatbot basado en LLM para el análisis avanzado de datos con Redash first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/chatbot-basado-en-llm-para-analisis-avanzado-de-datos-con-redash/feed/ 0
Crea un chatbot LLM en un Mac M1 https://desa.planetachatbot.com/crea-chatbot-llm-en-mac-m1/?utm_source=rss&utm_medium=rss&utm_campaign=crea-chatbot-llm-en-mac-m1 https://desa.planetachatbot.com/crea-chatbot-llm-en-mac-m1/#respond Tue, 11 Jun 2024 06:00:13 +0000 https://desa.planetachatbot.com/?p=17821 Este es un tutorial para saber integrar un modelo generativo (chatbot LLM) como un servidor local utilizando LLAMA2 y GASP «CPU» como recursos. Este tutorial es para que los estudiantes consulten localmente un gran modelo de lenguaje (LLM). También recomendaría otros métodos para aprender a implementar en la nube como este tutorial de AWS o […]

The post Crea un chatbot LLM en un Mac M1 first appeared on Planeta Chatbot.

]]>
Este es un tutorial para saber integrar un modelo generativo (chatbot LLM) como un servidor local utilizando LLAMA2 y GASP «CPU» como recursos. Este tutorial es para que los estudiantes consulten localmente un gran modelo de lenguaje (LLM). También recomendaría otros métodos para aprender a implementar en la nube como este tutorial de AWS o una mejor implementación local como LocalAI. Incluso Reddit tiene algunos buenos recursos para aprender a construir localmente. En cualquier caso, el propósito de este tutorial es permitirte implementar un chatbot usando Python en un sistema Mac o Linux. Todo el código asociado a este post está disponible en GitHub.

Requisitos de instalación

Los requisitos para ejecutar esto en un M1 se obtienen en parte a través del archivo requirements.txt de GitHub que se puede utilizar para construir un entorno Anaconda. Para aquellos que no tienen Anaconda encontrarlo aquí. Descarga la carpeta de GitHub y construye el entorno chatbot-llm con el siguiente comando:

conda create -n chatbot-llm –file requirements.txt python=3.10
conda activate chatbot-llm

A continuación, necesitamos instalar algunos otros paquetes usando pip que no están disponibles a través de conda. Además, para que el LLM funcione en un sistema Mac o Linux debemos establecer los argumentos de cmake usando el siguiente comando.

# Linux and Mac
CMAKE_ARGS=»-DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=OpenBLAS»

pip install llama-cpp-python –force-reinstall –upgrade –no-cache-dir
pip install sse_starlette
pip install starlette_context
pip install pydantic_settings

Descarga y activación del modelo LLAMA-2

Ahora es el momento de descargar el modelo. Para este ejemplo, estamos utilizando un LLM relativamente pequeño (sólo unos 4,78 GB). Puedes descargar el modelo desde Hugging Face.

mkdir -p models/7B
wget -O models/7B/llama-2-7b-chat.Q5_K_M.gguf https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGUF/resolve/main/llama-2-7b-chat.Q5_K_M.gguf?download=true

Una vez que el modelo y los paquetes han sido instalados, estamos listos para ejecutar el LLM localmente. Comenzamos llamando al llama_cpp.server con el modelo LLAMA-2 descargado. Esta combinación actúa como ChatGPT (servidor) y GPT-4 (modelo) respectivamente.

python3 -m llama_cpp.server –model models/7B/llama-2-7b-chat.Q5_K_M.gguf

Consulta del modelo

Esto iniciará un servidor en localhost:8000 que podremos consultar en el siguiente paso. El servidor y el modelo están ahora listos para la entrada de usuario. Estamos consultando el servidor y el modelo utilizando query.py con nuestra pregunta de elección. Para comenzar la consulta, debemos abrir una nueva pestaña de terminal y activar nuestro entorno conda de nuevo.

conda activate chatbot-llm

En el archivo query.py actual, la porción de contenido dentro de la lista de mensajes es lo que usted como usuario puede cambiar para obtener una respuesta diferente del modelo. Además, el parámetro max_tokens permite al usuario ajustar la longitud de la respuesta LLM a la entrada. Nota Si el máximo de tokens es menor que la respuesta proyectada, el texto puede cortarse a mitad de la frase. Nuestro prompt es el siguiente:

«Háblame de los Pokémon iniciales de la primera generación de juegos».

Para ejecutar la consulta contra el modelo, llamamos al script de consulta.

export MODEL=»models/7B/llama-2-7b-chat.Q5_K_M.gguf»
python query.py

Después de ejecutar el script de consulta, hay una pausa que puede ser algo sustancial dependiendo de su pregunta. En nuestro caso, la respuesta del modelo no se produce hasta pasados casi 3 MINUTOS. (179.966 s). Eso parece mucho tiempo y se compara con la ejecución de los modelos en línea, pero todo el cálculo se realiza localmente en el hardware disponible. Las limitaciones de memoria, las velocidades de procesamiento de la CPU y la falta de otras optimizaciones hacen que este proceso sea mucho más largo. A pesar de que se tarda un tiempo aquí está la salida con max_tokens = 500:

«Háblame de los Pokémon iniciales de la primera generación de juegos».

Por supuesto. La primera generación de juegos Pokémon, también conocida como Generación I, incluye los siguientes Pokémon iniciales:

  1. Bulbasaur (tipo Hierba/Veneno) – Pokémon de tipo planta con cuerpo verde y marrón, Bulbasaur es conocido por su capacidad de fotosíntesis y por usar sus lianas para atacar a sus oponentes.
  2. Charmander (Tipo Fuego) – Pokémon de tipo lagarto con cuerpo naranja y amarillo, Charmander es conocido por su ardiente personalidad y su habilidad para respirar fuego.
  3. Squirtle (tipo Agua) – Pokémon con forma de tortuga y cuerpo azul y rojo, Squirtle es conocido por su velocidad y agilidad en el agua, así como por su capacidad para lanzar potentes chorros de agua.

Cada uno de estos Pokémon iniciales tiene habilidades y características únicas que los hacen idóneos para diferentes estrategias de batalla y estilos de juego. ¿Sobre cuál te gustaría saber más?

Esta respuesta es realmente detallada dada la contundencia de la consulta y una emocionante demostración de la potencia de los LLM. No recomendaría ejecutar estos modelos utilizando procesamiento en serie (CPU y «CPU» como en un M1) debido al tiempo que se tarda en completar la respuesta. Si está disponible, intente ejecutar modelos locales utilizando una GPU, lo que aceleraría el tiempo de procesamiento, o simplemente sea como yo y utilice ChatGPT de OpenAI.

Recapitulación y agradecimientos

chatbot

En esta demostración, instalamos un servidor LLM (llama_cpp.server) y un modelo (LLAMA-2) localmente en un Mac. Pudimos desplegar nuestro propio LLM local. Luego pudimos consultar el servidor/modelo y ajustar el tamaño de la respuesta. ¡Enhorabuena, has construido tu propio LLM! La inspiración para este trabajo y algunos de los bloques de construcción del código provienen de Youness Mansar.

Siéntete libre de usar o compartir el código que está disponible en GitHub. Mi nombre es Doctor Cody Glickman y me puedes encontrar en LinkedIn. Asegúrate de revisar algunos de mis otros artículos para los proyectos que abarcan una amplia gama de contenidos de data science y machine learning.

The post Crea un chatbot LLM en un Mac M1 first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/crea-chatbot-llm-en-mac-m1/feed/ 0
Cómo utilizar la API ChatGPT para la interacción directa desde Colab o Databricks https://desa.planetachatbot.com/como-utilizar-api-chatgpt-para-interaccion-directa-desde-colab-o-databricks/?utm_source=rss&utm_medium=rss&utm_campaign=como-utilizar-api-chatgpt-para-interaccion-directa-desde-colab-o-databricks https://desa.planetachatbot.com/como-utilizar-api-chatgpt-para-interaccion-directa-desde-colab-o-databricks/#respond Thu, 23 May 2024 06:00:31 +0000 https://desa.planetachatbot.com/?p=17696 ¿Te has preguntado cómo puedes utilizar la API ChatGPT de OpenAI para interactuar directamente con los algoritmos de GPT? Es fácil, gratuito y, además, más potente que la interfaz web «clásica» de www.openai.com. En el siguiente tutorial, te guiaré a través de unos sencillos pasos que te permitirán utilizar GPT para generar texto, crear imágenes […]

The post Cómo utilizar la API ChatGPT para la interacción directa desde Colab o Databricks first appeared on Planeta Chatbot.

]]>
¿Te has preguntado cómo puedes utilizar la API ChatGPT de OpenAI para interactuar directamente con los algoritmos de GPT? Es fácil, gratuito y, además, más potente que la interfaz web «clásica» de www.openai.com. En el siguiente tutorial, te guiaré a través de unos sencillos pasos que te permitirán utilizar GPT para generar texto, crear imágenes o depurar tu código. A medida que aumenta el uso de ChatGPT y otras soluciones de procesamiento del lenguaje natural (NLP), también lo hace el número de herramientas y plataformas que permiten a los usuarios interactuar con estas funciones de vanguardia. Una de las opciones más populares es la interfaz web OpenAI, que ha recibido elogios generalizados por su capacidad para gestionar tareas complejas de NLP.

Hoy, sin embargo, exploraremos una alternativa: la API ChatGPT. Este artículo se divide en tres secciones principales:

  1. Configura tu cuenta OpenAI y crea una clave API
  2. Establece la conexión general desde Google Colab
  3. Prueba diferentes peticiones: generación de texto, creación de imágenes & corrección de errores

Nota: Aunque este tutorial se ha realizado en Google Colab (gratuito), puede que quieras probar otros entornos. Por ejemplo, todo el código se aplicó también en Databricks.

1. Configura tu cuenta OpenAI y crea una clave API

Para interactuar con los algoritmos de GPT, necesitas registrarte en una cuenta OpenAI (gratuita): https://platform.openai.com/signup/

Una vez que te hayas registrado y dado de alta, necesitarás crear una clave API que te permitirá enviar peticiones a OpenAI desde servicios de terceros como Google Colab o Databricks. Navega hasta la sección «Ver clave de API» a través del menú de usuario, o utiliza el siguiente enlace: https://platform.openai.com/account/api-keys.

En esta sección, simplemente haz clic en «Crear nueva clave secreta» y guarda la clave creada en algún lugar de tu ordenador (¡la necesitarás pronto!):

Ten en cuenta que la API ChatGPT ofrece un uso de prueba gratuito (a partir de hoy) con solicitudes y tokens limitados por minuto. Consulte los límites de velocidad a continuación [1]:

  • Usuarios de prueba gratuitos: 20 RPM 40000 TPM
  • Usuarios de pago por uso (primeras 48 horas): 60 RPM 60000 TPM
  • Usuarios de pago (después de 48 horas): 3500 RPM 90000 TPM

(RPM = peticiones por minuto; TPM = tokens por minuto)

2. Establecer la conexión general desde Colab

La forma más fácil y directa de probar la API es utilizar Google Colaboratory («Colab»), que es algo así como «un entorno gratuito de cuadernos Jupyter que no requiere configuración y se ejecuta completamente en la nube». Aunque hay muchos entornos más profesionales que quizá quieras explorar (por ejemplo, Databricks), creo que Colab no es un mal servicio para dar tus primeros pasos con la API ChatGPT.

Para configurar un entorno básico para ChatGPT dentro de Colab puedes seguir los siguientes pasos:

  1. Abre https://colab.research.google.com/ y regístrate para obtener una cuenta gratuita
  2. Crear un nuevo cuaderno en Colab
  3. Instala y utiliza el paquete openai:

pip install openai

Para ejecutar una simple petición de chat a la API usando el modelo turbo GPT 3.5 (ver otros modelos disponibles en su documentación enlazada al final de este artículo), similar a lo que conoces de la interfaz web de OpenAI, puedes simplemente ejecutar las siguientes líneas de código en tu bloc de notas:

import os
import openai

openai.api_key = «please-paste-your-API-key-here»

openai.ChatCompletion.create(
model=»gpt-3.5-turbo»,
messages=[
{«role»: «user», «content»: «Hello ChatGPT, does this work?»}
]
)

En cuanto ejecutes el comando en Colab, recibirás como respuesta un objeto JSON que contiene la respuesta esperada (Ha sido fácil, ¿verdad?):

¡Hola! Como modelo lingüístico de IA, no tengo el contexto de a qué se refiere «esto». ¿Podrías especificar a qué te refieres para que pueda ayudarte mejor?

<OpenAIObject chat.completion id=chatcmpl-70ErnAfGGwU7GhMXzCcLGyUvr4hA2 at 0x7f097f0a5f40> JSON: {
«choices»: [
{
«finish_reason»: «stop»,
«index»: 0,
«message»: {
«content»: «Hello! As an AI language model, I don’t have the context of what \»this\» refers to. Could you please specify what you are referring to so I can assist you better?»,
«role»: «assistant»
}
}
],
«created»: 1680291503,
«id»: «chatcmpl-70ErnAfGGwU7GhMXzCcLGyUvr4hA2»,
«model»: «gpt-3.5-turbo-0301»,
«object»: «chat.completion»,
«usage»: {
«completion_tokens»: 38,
«prompt_tokens»: 17,
«total_tokens»: 55
}
}

Además, el objeto JSON proporciona información sobre el número de tokens utilizados y el motivo del fin de la solicitud. Si sólo deseas imprimir la respuesta de texto, puedes acceder a este elemento modificando ligeramente tu código:

import os
import openai

openai.api_key = «please-paste-your-API-key-here»

response = openai.ChatCompletion.create(
model=»gpt-3.5-turbo»,
messages=[
{«role»: «user», «content»: «Hello ChatGPT, does this work?»}
]
)

print(response.choices[0].message.content)

3. Probar diferentes peticiones: generación de texto, creación de imágenes y corrección de errores

Si estás tan emocionado como yo cuando descubrí esto, puedes empezar a enviar un montón de peticiones diferentes a la API. Una forma útil de modularizar tu código es crear algunas funciones útiles que quieras llamar para diferentes propósitos. Déjame darte algunas ideas.

Función para chatear con ChatGPT

El siguiente código simplemente resume el trabajo hecho hasta ahora en una función invocable que te permite hacer cualquier petición a GPT y obtener sólo la respuesta de texto como resultado.

import os
import openai

openai.api_key = «please-paste-your-API-key-here»

def chatWithGPT(prompt):
completion = openai.ChatCompletion.create(
model=»gpt-3.5-turbo»,
messages=[
{«role»: «user», «content»: prompt}
]
)
return print(completion.choices[0].message.content)

¿Crees que tiene sentido aprender python? ¡Preguntemos a GPT!

chatWithGPT(«is it a good idea to start learning python?»)

Como modelo de lenguaje de IA, no puedo dar opiniones personales, pero sí puedo decir que Python es un lenguaje de programación popular y muy utilizado, muy apreciado tanto por principiantes como por desarrolladores experimentados. Cuenta con el apoyo de una amplia comunidad, un gran número de bibliotecas y una sintaxis sencilla que lo hace fácil de entender para los principiantes. Es útil para diversas aplicaciones, como el análisis de datos, el desarrollo web, el aprendizaje automático y mucho más. Por lo tanto, podría ser una buena idea empezar a aprender Python si quieres seguir una carrera en programación o quieres añadir otra habilidad a tu currículum.

Función para corregir errores en tu código

Otro caso de uso de ChatGPT es obtener ideas para arreglar tu código. Imagina que tu comando Python devuelve un error y quieres obtener consejos sobre qué hacer sin usar Google o StackOverflow:

import os
import openai

openai.api_key = «please-paste-your-API-key-here»

def fixMyCode(code):
completion = openai.ChatCompletion.create(
model=»gpt-3.5-turbo»,
messages=[
{«role»: «user», «content»: «find error in my python script below and fix it: » + code}
]
)
return print(completion.choices[0].message.content)

Verás mi código python ha lanzado un error, y no sé por qué…

fixMyCode(«»»

def some_function():
print(«I’m going to sleep»)
time.sleep(10)
print(«I’m awake again»)


some_function()

«»»)

Verás, mi código python ha arrojado un error, y no sé por qué…No es ninguna sorpresa, pero ChatGPT descubrió inmediatamente que me había olvidado de importar el módulo antes de utilizarlo. Esto puede ser muy útil en el día a día, sobre todo cuando puedes pedir ayuda directamente desde el entorno de programación.

Función para crear imágenes

El último caso de uso que me gustaría presentar aquí es la creación de imágenes. La propia petición devuelve un hipervínculo que contiene la imagen. Usando la librería IPhython, puedes mostrar la imagen directamente en tu cuaderno.

import IPython
import os
import openai

openai.api_key = «please-paste-your-API-key-here»

def createImageWithGPT(prompt):
completion = openai.Image.create(
prompt=prompt,
n=1,
size=»512×512″
)
return IPython.display.HTML(«<img src =» + completion.data[0].url + «>»)

Seamos creativos y pidamos un gato conduciendo un monopatín.

createImageWithGPT(«Cat driving a skateboard»)

API ChatGPT

Resumen

Con la API ChatGPT, las empresas y los particulares pueden incorporar chatbots a su flujo de trabajo de forma fácil y asequible, sin los conocimientos técnicos o los amplios recursos que suelen ser necesarios. La API también puede utilizarse para crear asistentes virtuales, tutores personales, etc. Recomiendo la documentación puesta a disposición por OpenAI para su API: https://platform.openai.com/docs/api-reference.

En resumen, es fácil utilizar la API en tu entorno de programación. Esto no sólo puede ser útil para la depuración directa de tu código, sino que también ha demostrado tasas de respuesta más estables en comparación con la interfaz web de OpenAI (a veces no disponible). Con la capacidad de entender el lenguaje natural y volverse más inteligente con el tiempo, ChatGPT tiene el potencial de revolucionar la forma en que las empresas interactúan con sus clientes y agilizar sus flujos de trabajo. Pruébelo usted mismo y experimente el futuro de los chatbots.

The post Cómo utilizar la API ChatGPT para la interacción directa desde Colab o Databricks first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/como-utilizar-api-chatgpt-para-interaccion-directa-desde-colab-o-databricks/feed/ 0
Creación del chatbot LangChain más básico https://desa.planetachatbot.com/creacion-chatbot-langchain-mas-basico/?utm_source=rss&utm_medium=rss&utm_campaign=creacion-chatbot-langchain-mas-basico https://desa.planetachatbot.com/creacion-chatbot-langchain-mas-basico/#respond Thu, 16 May 2024 07:37:26 +0000 https://desa.planetachatbot.com/?p=17650 Chatbots tradicionales Teniendo en cuenta la imagen inferior, los chatbots tradicionales constan en realidad de cuatro elementos básicos. En el pasado reciente ha habido numerosos intentos de reimaginar esta estructura. El objetivo principal de estos intentos era relajar la rigidez de los elementos arquitectónicos fijos y codificados de un chatbot. Comprensión del lenguaje natural (NLU) […]

The post Creación del chatbot LangChain más básico first appeared on Planeta Chatbot.

]]>
Chatbots tradicionales

Teniendo en cuenta la imagen inferior, los chatbots tradicionales constan en realidad de cuatro elementos básicos. En el pasado reciente ha habido numerosos intentos de reimaginar esta estructura. El objetivo principal de estos intentos era relajar la rigidez de los elementos arquitectónicos fijos y codificados de un chatbot.

Comprensión del lenguaje natural (NLU)

El motor NLU facilita la comprensión de intenciones y entidades. Esta es la única parte de IA del chatbot, en la que las entradas del usuario se envían al motor NLU y las intenciones y entidades se detectan a partir de las entradas.

Normalmente hay una interfaz gráfica de usuario para definir los datos de entrenamiento del motor NLU e iniciar el entrenamiento del modelo basado en estos datos de entrenamiento. Las ventajas típicas de los motores NLU son:

  • Existen muchos modelos de código abierto.
  • Los motores de NLU ocupan poco espacio y no consumen muchos recursos; las instalaciones locales y periféricas son factibles.
  • La interfaz de usuario no es técnica y se necesitan pocos datos de entrenamiento.
  • Los NLU existen desde hace tanto tiempo que existen grandes corpus de entidades con nombre, junto con entidades predefinidas y datos de entrenamiento para sectores verticales específicos. Por ejemplo, banca, servicios financieros, recursos humanos, etc.
  • El tiempo de entrenamiento de los modelos es corto y, en un entorno de producción, los modelos pueden entrenarse varias veces al día.

Los datos de entrenamiento de NLU fueron una de las áreas en las que se introdujeron los LLM por primera vez. Los LLM se utilizaron para generar datos de entrenamiento para el modelo NLU a partir de conversaciones existentes y datos de entrenamiento de muestra.

Flujo de conversación y gestión de diálogos

El flujo y la lógica del diálogo están diseñados y construidos dentro de una GUI de nocode o lowcode. El flujo y la lógica son básicamente un flujo predefinido con puntos lógicos predefinidos. La conversación fluye según los datos de entrada coincidan con ciertos criterios de la puerta lógica.

Se ha intentado introducir flexibilidad en el flujo para dotarlo de cierta inteligencia.

Capa de abstracción de mensajes

La capa de abstracción de mensajes contiene respuestas predefinidas del bot para cada turno de diálogo. Estas respuestas son fijas y, en algunos casos, se utiliza una plantilla para insertar datos y crear mensajes personalizados.

La gestión de los mensajes supone un reto, sobre todo cuando la aplicación de chatbot crece y, debido a la naturaleza estática de los mensajes, el número total de mensajes puede ser significativo. La introducción de chatbots multilingües añade una complejidad considerable.

Cada vez que hay que cambiar el tono o el personaje del chatbot, hay que revisar y actualizar todos estos mensajes.

Esta es también una de las áreas en las que se introdujeron por primera vez los LLM para aprovechar la potencia de la Generación de Lenguaje Natural (NLG) dentro de los LLM.

Las preguntas fuera del dominio se gestionaban mediante bases de conocimiento y búsquedas de similitud semántica. Estas bases de conocimiento se utilizaban principalmente para QnA y las soluciones hacían uso de la búsqueda semántica. En muchos aspectos, esto podría considerarse como una versión temprana de RAG.

Teniendo en cuenta la imagen que se muestra a continuación, muchas organizaciones y proveedores de tecnología están realizando la transición de los Chatbots tradicionales a la introducción de Grandes Modelos de Lenguaje.

La imagen que se muestra a continuación describe los distintos elementos y características que componen un Modelo Lingüístico (LLM). En consecuencia, el reto consiste en acceder a cada una de estas características en el momento adecuado, garantizando la estabilidad, la previsibilidad y, hasta cierto punto, la reproducibilidad.

chatbot

Estructura de LangChain

Introducción

Los chatbots representan una de las aplicaciones más comunes de los modelos de grandes lenguajes (LLM).

Las capacidades fundamentales de los chatbots incluyen la realización de diálogos extensos (que requieren memoria) y con estado, y proporcionar a los usuarios respuestas pertinentes derivadas de información relevante.

El caso de uso es importante

Crear un chatbot implica evaluar diversas técnicas, cada una de las cuales ofrece ventajas y desventajas únicas.

Estas consideraciones dependen de los tipos de consultas que se espera que el chatbot aborde con eficacia.

Los chatbots suelen recurrir a la generación aumentada por recuperación (RAG) cuando acceden a datos privados para mejorar su capacidad de respuesta a consultas específicas del dominio.

Además, los diseñadores pueden optar por implementar mecanismos de enrutamiento a través de múltiples fuentes de datos, garantizando la selección del contexto más relevante para ofrecer respuestas precisas.

El uso de formas especializadas de historial o memoria de chat más allá del mero intercambio de mensajes puede enriquecer aún más las capacidades del bot.

Arquitectura básica de Chatbot

Chroma es una base de datos para construir aplicaciones de IA con embeddings, y necesita ser instalada.

Para este chatbot, OpenAI se utiliza como la columna vertebral del chatbot con el modelo gpt-3.5-turbo-1106 definido.

El código también muestra cómo se pasan los mensajes al historial de conversación. Esta idea básica sustenta la capacidad de un chatbot para interactuar conversacionalmente.

Se hace uso de la plantilla Prompt para facilitar el formateo. Y el MessagesPlaceholder como se ve a continuación inserta los mensajes de chat pasados a la entrada de la cadena como chat_history directamente en el prompt.

Ejemplo completo de LangChain

El siguiente código puede copiarse literalmente y pegarse en un cuaderno Colab. El único cambio que tendrás que hacer, es añadir tu clave API de OpenAI en la línea cuatro…

%pip install –upgrade –quiet langchain langchain-openai langchain-chroma
##########
import os
os.environ[‘OPENAI_API_KEY’] = str(«<Your API Key Goes Here>»)
##########
from langchain_openai import ChatOpenAI
chat = ChatOpenAI(model=»gpt-3.5-turbo-1106″, temperature=0.2)

##########
from langchain_core.messages import HumanMessage

chat.invoke(
[

HumanMessage(
content=»Translate this sentence from English to French: I love programming.»
)
]
)
########## Generate Response 1
chat.invoke([HumanMessage(content=»What did you just say?»)])
##########
from langchain_core.messages import AIMessage

chat.invoke(
[

HumanMessage(
content=»Translate this sentence from English to French: I love programming.»
),
AIMessage(content=»J’adore la programmation.»),
HumanMessage(content=»What did you just say?»),
]
)

########## Generate Response 2
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages(
[
(
«system»,
«You are a helpful assistant. Answer all questions to the best of your ability.»,

),
MessagesPlaceholder(variable_name=»messages»),
]
)

chain = prompt | chat
##########
chain.invoke(
{
«messages»: [
HumanMessage(
content=»Translate this sentence from English to French: I love programming.»
),
AIMessage(content=»J’adore la programmation.»),
HumanMessage(content=»What did you just say?»),
],
}

)
##########
demo_ephemeral_chat_history.add_user_message(
«Translate this sentence from English to French: I love programming.»
)

response = chain.invoke({«messages»: demo_ephemeral_chat_history.messages})

response
##########
demo_ephemeral_chat_history.add_ai_message(response)

demo_ephemeral_chat_history.add_user_message(«What did you just say?»)

chain.invoke({«messages»: demo_ephemeral_chat_history.messages})

En conclusión

Los grandes modelos lingüísticos (LLM) han revolucionado el desarrollo tradicional de chatbots al ofrecer capacidades sin precedentes de comprensión del lenguaje natural y, sobre todo, de generación.

A diferencia de los anteriores enfoques basados en reglas o plantillas, los LLM permiten a los chatbots comprender y generar respuestas similares a las humanas de forma dinámica, adaptándose a diversos contextos conversacionales.

Este cambio ha trastornado el desarrollo de chatbots y las arquitecturas establecidas y asentadas. Al reducir la dependencia de reglas elaboradas a mano y bases de conocimiento específicas del dominio.

Además, los LLM facilitan la creación de chatbots más sofisticados capaces de manejar una gama más amplia de consultas con mayor precisión y fluidez.

La atención de los desarrolladores se ha desplazado hacia el perfeccionamiento de los modelos, la GAR, el aprendizaje en contexto (ICL) y otras técnicas avanzadas, en lugar de centrarse únicamente en la elaboración de guiones de diálogo.


 Sígueme en LinkedIn para estar al día sobre la IA conversacional 

Actualmente soy el Evangelista Jefe @ HumanFirst. Exploro y escribo sobre todas las cosas en la intersección de la IA y el lenguaje; que van desde LLMs, Chatbots, Voicebots, marcos de desarrollo, espacios latentes centrados en datos y más.

The post Creación del chatbot LangChain más básico first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/creacion-chatbot-langchain-mas-basico/feed/ 0
¿Cómo competir cuando se puede copiar una startup de IA con Whisper y ChatGPT en 3 minutos? https://desa.planetachatbot.com/como-competir-cuando-se-puede-copiar-startup-de-ia-con-whisper-y-chatgpt-en-3-minutos/?utm_source=rss&utm_medium=rss&utm_campaign=como-competir-cuando-se-puede-copiar-startup-de-ia-con-whisper-y-chatgpt-en-3-minutos https://desa.planetachatbot.com/como-competir-cuando-se-puede-copiar-startup-de-ia-con-whisper-y-chatgpt-en-3-minutos/#respond Thu, 09 May 2024 06:00:38 +0000 https://desa.planetachatbot.com/?p=17605 Hace poco grabé un vídeo en YouTube en el que compartía algunos momentos emocionantes de una conferencia a la que asistí. Una de las startups que encontré me llamó mucho la atención. Tenía esta increíble solución impulsada por IA que podría ayudar al proceso de contratación de nuestra empresa. Me hizo pensar en lo fácil […]

The post ¿Cómo competir cuando se puede copiar una startup de IA con Whisper y ChatGPT en 3 minutos? first appeared on Planeta Chatbot.

]]>
Hace poco grabé un vídeo en YouTube en el que compartía algunos momentos emocionantes de una conferencia a la que asistí. Una de las startups que encontré me llamó mucho la atención. Tenía esta increíble solución impulsada por IA que podría ayudar al proceso de contratación de nuestra empresa. Me hizo pensar en lo fácil que es replicar esta funcionalidad. Todo lo que tenía que hacer era traducir el audio a texto y chatear con GPT:

Paso 1: obtener un texto de voz

import whisper
model = whisper.load_model(«medium»)
result = model.transcribe(«job.m4a»)

Buenos días, equipo de Neurons Lab. He encontrado vuestro puesto para data scientist, comprobación de hipótesis y aprendizaje profundo, y quiero solicitarlo. Vivo en Italia. Mi nombre es Alex Honcher y ya he trabajado en ciencia de datos durante los últimos cinco años. Mi formación es licenciatura en informática y máster en matemáticas, ambos en el Politécnico de Milán. Primero trabajé como becario en Banca Popolare durante un año. Trabajé en la predicción de plazos para la banca minorista con un equipo de cuatro personas. En este trabajo yo estaba trabajando principalmente con SecondLearn y Pandas. Y después de esto me mudé y trabajé durante los últimos cuatro años en una startup. La startup también era FinTech, pero relacionada con la gestión de inversiones. Y yo estaba trabajando en la predicción de los mercados. Estaba construyendo modelos de aprendizaje automático en diferentes conjuntos de datos, principalmente series temporales, pero tenía que limpiarlos. Los datos eran más grandes, así que utilizaba AWS SageMaker para procesarlos. También entrenaba modelos allí y los implementaba. Así que entiendo todo el ciclo de MLops parte. Y me gusta mucho que tengas la política remota. Y creo que encajo muy bien en su área de responsabilidad. Puedo hacer modelado y pruebas. También tengo experiencia en Git. Siempre uso Git. Y las habilidades, mi inglés es bueno. Hago aprendizaje automático y modelado estadístico. Y me gusta mucho lo que ofrecen y también la posibilidad de trabajar a tiempo parcial. Así que por favor considere mi aplicación a la posición. Muchas Gracias

Paso 2: estructurar el texto en un CV

CV

Nombre: Alex Honcher
Lugar de trabajo: Italia

Estudios:

Licenciado en Informática, Politecnico di Milano
Máster en Matemáticas, Politecnico di Milano
Experiencia laboral:

Prácticas en Banca Popolare (1 año)

Trabajé en la predicción de plazos para el sector de la banca minorista
Colaboración con un equipo de cuatro personas
Utilización de SecondLearn y Pandas para el análisis de datos

Startup (4 años)

Trabajé en una startup FinTech centrada en la gestión de inversiones
Desarrolló modelos de aprendizaje automático para la predicción del mercado
Trabajo extensivo con series temporales de datos
Limpieza y procesamiento de datos con AWS SageMaker
Entrenó e implementó modelos de aprendizaje automático
Experiencia en todo el ciclo MLops

Competencias:

Machine Learning
Modelado estadístico
Control de versiones Git
Dominio del inglés
Otros:

Interesado en la política de trabajo remoto
Capacidad para trabajar a tiempo parcial

Paso 3: pedir que se adapte un CV a los puestos paso a paso

Por supuesto. Aquí tienes una tabla en la que se compara el CV del candidato con la descripción del puesto, junto con una puntuación final de coincidencia:

Criterios de la descripción del puestoCV del candidato
Modelización estadística y comprobación de hipótesis.
Diseño, entrenamiento y validación de resultados de algoritmos de aprendizaje automático.
Escribir SQL limpio y eficienteProbablemente, basado en experiencia en ciencia de datos
Construir y probar aplicaciones Python.
Construir redes neuronales profundas con herramientas modernas (por ejemplo, PyTorch o Tensorflow).
Colaborar a través de Git
Aprendizaje automático e ingeniería
Modelado estadístico
Minería y análisis de datos
Inglés avanzado, buena comunicación con las partes interesadas del negocio
Desarrollo de documentaciónProbablemente, basado en experiencia en ciencia de datos
Experiencia con aprendizaje en línea, aprendizaje de refuerzo, algoritmos de bandidos contextualesNo se menciona en el CV
Experiencia en el lanzamiento y la validación de campañas en línea mediante pruebas A/B o los métodos antes mencionados.No se menciona en el CV
Experiencia previa en juegos online, comercio electrónico y entretenimiento o industrias similaresExperiencia relevante en FinTech y predicción de mercados
Trabajo a distancia desde cualquier lugarInterés expreso en la política de trabajo a distancia
Flexibilidad del horario laboralInterés manifestado por el trabajo a tiempo parcial

La estructura es excelente, e incluso se puede puntuar y empaquetar como JSON o cualquier otro formato para su visualización en el sitio web. Pero me hizo preguntarme, ¿dónde está la defensa? ¿Dónde está la singularidad? ¿Cómo pueden las startups de IA diferenciarse unas de otras e incluso de las startups o empresas de software que no son de IA?

Las startups de IA están en apuros

Las startups de IA ganan menos y son más difíciles de crear:

La mayor parte de tu negocio procederá del long tail y nunca tendrás datos suficientes para ello. Ilustración.

Este es un precio clásico de Andreessen & Horowitz escrito en 2019. Los programas de IA no son lo mismo que los programas SaaS que «solo» se ejecutan en la nube y tienen múltiples golpes de margen:

  • La infraestructura implica trabajo humano ad-hoc (etiquetado de datos y manejo de casos edge).
  • Los casos edge no son «edge» per se: la mayor parte de tu negocio vendrá de ellos y nunca tendrás suficientes datos «solo para entrenar IA».
  • Los «efectos de los datos» son un mito (la mayoría de los datos recogidos serán esencialmente los mismos) y la I+D ya no es un stopper.

Los algoritmos ya no son un stopper (al menos no para ti)

IA
La computación en nube se está abaratando para todos. Los proyectos de código abierto están abiertos a todo el mundo. ¿Qué tienes que sea único? Ilustración.

Los gráficos, creo, ya se explican por sí mismos. Todo el mundo puede ejecutar los mismos modelos de IA abierta utilizando los mismos proveedores de nube que tú. A menudo oigo decir que tus datos son únicos y que nadie más tiene acceso a ellos. Bueno, si tus datos son realmente tan únicos, significa que lo más probable es que no sea suficiente para entrenar un modelo de IA de última generación realmente bueno a partir de ellos. Todavía se puede construir una máquina de toma de decisiones automatizada muy decente y única y un negocio a partir de ella, pero no será un negocio de IA tal y como lo vemos hoy en día.

¿Volver a las raíces?

Los LLM y la ingeniería rápida te llevan a lo conocido. Los otros 3 cuadrantes son negocios, operaciones y tecnología «real». Ilustración.

Si la informática, los modelos de IA, los datos y la ingeniería rápida no son un stopper, ¿qué lo es?

«Negocios» clásicos

Este increíble artículo de NFX plantea cuestiones fundamentales sobre tu negocio. Me gusta especialmente la pregunta: «Si eliminas la palabra “IA” de tu discurso, ¿sigue siendo un discurso ganador?» O esta otra: «¿Se tarda más de 60 segundos con ChatGPT en realizar la misma tarea?» Nuestro ejemplo de voz y contratación puede reducirse fácilmente a menos de 60 segundos. Volvemos a los orígenes: comprender los problemas reales de los clientes, analizar la cadena de valor e inyectar automatización donde realmente importa.

«Operaciones» clásicas

Cuando todo el mundo tiene los mismos LLM y centros en la nube, la competencia se reduce al triángulo «dorado» de velocidad, costes y calidad. Las nuevas preguntas importantes son: ¿Construir tu propio LLM? ¿Ejecutarlo en tu propia nube? ¿Optimizar la arquitectura de la nube? ¿Eres dueño de tu propio hardware? ¿Encontrar un equipo de etiquetado de datos más barato? ¿Acelerar el progreso de tu equipo de IA? No se trata de retos creativos de ingeniería de avisos para «Chief Prompt Engineering Officers», sino más bien de tediosas y complejas tareas de gestión.

Conclusiones

En una era en la que los modelos de IA y la infraestructura en la nube son cada vez más accesibles para todos, las startups de IA se enfrentan al reto de la diferenciación. Sin embargo, si adoptan los principios empresariales clásicos, se centran en la experiencia de dominio y dan prioridad a la eficiencia operativa, las startups de IA pueden labrarse su posición única en el mercado. Aunque los algoritmos por sí solos pueden no ser un foso, la combinación de datos únicos, personalización, innovación continua y un enfoque centrado en el cliente puede diferenciarlos de la competencia.

The post ¿Cómo competir cuando se puede copiar una startup de IA con Whisper y ChatGPT en 3 minutos? first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/como-competir-cuando-se-puede-copiar-startup-de-ia-con-whisper-y-chatgpt-en-3-minutos/feed/ 0
Primeros pasos en la predicción de series temporales de datos con Facebook Prophet https://desa.planetachatbot.com/primeros-pasos-en-prediccion-de-series-temporales-de-datos-con-facebook-prophet/?utm_source=rss&utm_medium=rss&utm_campaign=primeros-pasos-en-prediccion-de-series-temporales-de-datos-con-facebook-prophet https://desa.planetachatbot.com/primeros-pasos-en-prediccion-de-series-temporales-de-datos-con-facebook-prophet/#respond Tue, 07 May 2024 06:00:00 +0000 https://desa.planetachatbot.com/?p=17590 Al iniciarse en data science, el análisis de series temporales es algo que a la gente le encantaría probar por sí misma. La idea general es aprender de los patrones históricos a lo largo del tiempo para predecir el futuro. Los casos de uso típicos podrían ser las predicciones meteorológicas o la previsión de ventas. […]

The post Primeros pasos en la predicción de series temporales de datos con Facebook Prophet first appeared on Planeta Chatbot.

]]>
Al iniciarse en data science, el análisis de series temporales es algo que a la gente le encantaría probar por sí misma. La idea general es aprender de los patrones históricos a lo largo del tiempo para predecir el futuro. Los casos de uso típicos podrían ser las predicciones meteorológicas o la previsión de ventas. Pero, ¿qué tiene que ver todo esto con el sabio profeta que te muestro en la imagen de cabecera?

Este artículo pretende eliminar las barreras de entrada para empezar con el análisis de series temporales en un tutorial práctico utilizando una de las herramientas más sencillas, cuyo nombre es Facebook Prophet dentro de Google Colab (¡ambas son gratuitas!). En caso de que quieras empezar inmediatamente, no dudes en saltarte los dos capítulos siguientes, en los que daré una breve introducción a los principios de las series temporales y a Facebook Prophet. Diviértete.

1. Principios generales del análisis de series temporales

Imagínate que eres gerente de una tienda de productos de consumo y deseas predecir la próxima demanda de productos para gestionar mejor la oferta. Un enfoque razonable de machine learning para este escenario es ejecutar algún análisis de series temporales que implica comprender, modelar y hacer predicciones basadas en puntos de datos secuenciales. [1]

El siguiente gráfico ilustra un desarrollo artificial de la demanda histórica de productos (línea azul oscuro) a lo largo del tiempo, que puede utilizarse para analizar un patrón de series temporales. Nuestro objetivo final sería predecir (línea de puntos rojos) la demanda futura real (línea azul claro) con la mayor precisión posible:

Una serie temporal suele descomponerse en tres componentes principales:

  1. Tendencia: el movimiento a largo plazo o la dirección general de los datos.
  2. Estacionalidad: fluctuaciones o patrones que se repiten a intervalos regulares.
  3. Residual/error: resto o variación sobrante en los datos.

La descomposición de una serie temporal en estos tres componentes, a menudo denominada descomposición aditiva o multiplicativa, permite a los analistas comprender mejor la estructura y las pautas subyacentes. Esta comprensión es esencial para seleccionar modelos de previsión adecuados y realizar predicciones precisas basadas en datos históricos. [2]

2. ¿Qué es Facebook Prophet?

Prophet es una herramienta de código abierto lanzada por el equipo de Data Science de Facebook que produce datos de previsión de series temporales basados en un modelo aditivo en el que se ajusta una tendencia no lineal con efectos de estacionalidad y vacaciones. Los principios de diseño permiten ajustar los parámetros sin mucho conocimiento del modelo subyacente, lo que hace que el método sea aplicable a equipos con menos conocimientos estadísticos. [3]

Prophet es especialmente adecuado para aplicaciones de previsión empresarial, y ha ganado popularidad debido a su facilidad de uso y eficacia en el manejo de una amplia gama de datos de series temporales. Como con cualquier herramienta, hay que tener en cuenta que, aunque Prophet es potente, la elección del método de previsión depende de las características específicas de los datos y de los objetivos del análisis. En general, no está garantizado que Prophet funcione mejor que otros modelos. Sin embargo, Prophet incorpora algunas funciones útiles, como el reflejo del cambio de estacionalidad antes y después de la COVID o el tratamiento de los cierres como vacaciones puntuales.

Para una introducción más detallada por parte de Meta (Facebook), te recomiendo ver el siguiente vídeo en YouTube.

En el siguiente tutorial, implementaremos y utilizaremos Prophet con Python. Sin embargo, ¡también puedes realizar tus análisis con R!

3. Tutorial práctico sobre el uso de Prophet

En caso de que tengas poca experiencia o no tengas acceso a tu entorno de codificación, te recomiendo hacer uso de Google Colaboratory («Colab») que es algo así como «un entorno de Jupyter notebook gratuito que no requiere configuración y se ejecuta completamente en la nube». Si bien este tutorial afirma más sobre la simplicidad y las ventajas de Colab, hay inconvenientes como la potencia de cálculo reducida en comparación con los entornos adecuados en la nube. Sin embargo, creo que Colab puede no ser un mal servicio para dar los primeros pasos con Prophet.

Para configurar un entorno básico de Análisis de Series Temporales dentro de Colab puedes seguir estos dos pasos:

  1. Abrir https://colab.research.google.com/ y registrarte para obtener una cuenta gratuita
  2. Crear un nuevo cuaderno dentro de Colab
  3. Instalar y utilizar el paquete prophet:

pip install prophet

from prophet import Prophet

Carga y preparación de datos

He cargado un pequeño conjunto de datos ficticio que representa la cantidad mensual de pasajeros de una empresa local de autobuses (2012-2023). Puedes encontrar los datos en GitHub.

Como primer paso, cargaremos los datos utilizando pandas y crearemos dos conjuntos de datos separados: un subconjunto de entrenamiento con los años 2012 a 2022 y un subconjunto de prueba con el año 2023. Entrenaremos nuestro modelo de series temporales con el primer subconjunto y trataremos de predecir el número de pasajeros en 2023. Con el segundo subconjunto, podremos validar la precisión más adelante.

import pandas as pd

df_data = pd.read_csv(«https://raw.githubusercontent.com/jonasdieckmann/prophet_tutorial/main/passengers.csv»)

df_data_train = df_data[df_data[«Month»] < «2023-01»]
df_data_test = df_data[df_data[«Month»] >= «2023-01»]

display(df_data_train)

La salida del comando de visualización puede verse a continuación. El conjunto de datos contiene dos columnas: la indicación de la combinación año-mes, así como una columna numérica con el importe de pasajeros en ese mes. Por defecto, Prophet está diseñado para trabajar con datos diarios (o incluso horarios), pero nos aseguraremos de que también se pueda utilizar el patrón mensual.

Descomposición de los datos de entrenamiento

Para comprender mejor los componentes de las series temporales dentro de nuestros datos ficticios, realizaremos una descomposición rápida. Para ello, importamos el método de la biblioteca statsmodels y ejecutamos la descomposición en nuestro conjunto de datos. Nos decidimos por un modelo aditivo e indicamos que un periodo contiene 12 elementos (meses) en nuestros datos. Un conjunto de datos diarios sería period=365.

from statsmodels.tsa.seasonal import seasonal_decompose

decompose = seasonal_decompose(df_data_train.Passengers, model=’additive’, extrapolate_trend=’freq’, period=12)

decompose.plot().show()

Este breve fragmento de código nos dará una impresión visual de las series temporales en sí, pero sobre todo de la tendencia, la estacionalidad y los residuos a lo largo del tiempo:

Ahora podemos ver claramente una tendencia al alza significativa en los últimos 10 años, así como un patrón de estacionalidad reconocible cada año. Siguiendo estas indicaciones, cabría esperar que el modelo predijera un nuevo aumento del número de pasajeros tras los picos estacionales del verano del año siguiente. Pero vamos a probarlo: ¡es hora de aplicar el aprendizaje automático!

Ajuste de modelos con Facebook Prophet

Para ajustar modelos en Prophet, es importante tener al menos una columna «ds» (fecha) e «y» (valor que se va a pronosticar). Debemos asegurarnos de que nuestras columnas tienen el mismo nombre.

df_train_prophet = df_data_train

# date variable needs to be named «ds» for prophet
df_train_prophet = df_train_prophet.rename(columns={«Month»: «ds»})

# target variable needs to be named «y» for prophet
df_train_prophet = df_train_prophet.rename(columns={«Passengers»: «y»})

Ahora puedes empezar la magia. El proceso para ajustar el modelo es bastante sencillo. Sin embargo, por favor, echa un vistazo a la documentación para hacerte una idea de la gran cantidad de opciones y parámetros que podríamos ajustar en este paso. Para simplificar las cosas, ajustaremos un modelo sencillo sin más ajustes por ahora, pero ten en cuenta que los datos del mundo real nunca son perfectos: sin duda necesitarás ajustar los parámetros en el futuro.

model_prophet = Prophet()
model_prophet.fit(df_train_prophet)

Eso es todo lo que tenemos que hacer para ajustar el modelo. ¡Hagamos algunas predicciones!

Hacer predicciones

Tenemos que hacer predicciones en una tabla que tenga una columna ‘ds’ con las fechas para las que quieres predicciones. Para configurar esta tabla, utiliza el método make_future_dataframe, y automáticamente incluirá las fechas históricas. De esta forma, podrás ver lo bien que el modelo se ajusta a los datos pasados y predice el futuro. Como manejamos datos mensuales, indicaremos la frecuencia con «freq=12» y pediremos un horizonte futuro de 12 meses («periods=12»).

df_future = model_prophet.make_future_dataframe(periods=12, freq=’MS’)
display(df_future)

Este nuevo conjunto de datos contiene tanto el periodo de entrenamiento como los 12 meses adicionales que queremos predecir:

Para realizar predicciones, basta con llamar al método predict de Prophet y proporcionar el futuro conjunto de datos. El resultado de la predicción contendrá un gran conjunto de datos con muchas columnas diferentes, pero nos centraremos únicamente en el valor predicho yhat, así como en los intervalos de incertidumbre yhat_inferior y yhat_superior.

forecast_prophet = model_prophet.predict(df_future)
forecast_prophet[[‘ds’, ‘yhat’, ‘yhat_lower’, ‘yhat_upper’]].round().tail()

La tabla siguiente nos da una idea de cómo se genera y almacena el resultado. Para agosto de 2023, el modelo predice un número de pasajeros de 532 personas. El intervalo de incertidumbre (que está fijado por defecto en el 80%) nos indica de forma sencilla que podemos esperar con toda probabilidad una cantidad de pasajeros de entre 508 y 556 personas en ese mes.

Por último, queremos visualizar los resultados para comprender mejor las predicciones y los intervalos.

Visualización de resultados

Para trazar los resultados, podemos utilizar las herramientas de trazado incorporadas en Prophet. Con el método de trazado, podemos mostrar los datos originales de la serie temporal junto con los valores pronosticados.

import matplotlib.pyplot as plt

# plot the time series
forecast_plot = model_prophet.plot(forecast_prophet)

# add a vertical line at the end of the training period
axes = forecast_plot.gca()
last_training_date = forecast_prophet[‘ds’].iloc[-12]
axes.axvline(x=last_training_date, color=’red’, linestyle=’–‘, label=’Training End’)

# plot true test data for the period after the red line
df_data_test[‘Month’] = pd.to_datetime(df_data_test[‘Month’])
plt.plot(df_data_test[‘Month’], df_data_test[‘Passengers’],’ro’, markersize=3, label=’True Test Data’)

# show the legend to distinguish between the lines
plt.legend()

Además del gráfico general de series temporales, hemos añadido una línea de puntos para indicar el final del periodo de entrenamiento y, por tanto, el inicio del periodo de predicción. Además, utilizamos el conjunto de datos de prueba reales que habíamos preparado al principio.

series temporales

Puede verse que nuestro modelo no es tan malo. La mayoría de los valores reales de pasajeros están dentro de los intervalos de incertidumbre previstos. Sin embargo, los meses de verano parecen seguir siendo demasiado pesimistas, lo cual es un patrón que ya podemos ver en años anteriores. Este es un buen momento para empezar a explorar los parámetros y características que podríamos utilizar con Prophet.

En nuestro ejemplo, la estacionalidad no es un factor aditivo constante, sino que crece con la tendencia a lo largo del tiempo. Por lo tanto, podríamos considerar cambiar el seasonality_mode de «aditivo» a «multiplicativo» durante el ajuste del modelo. [4]

Nuestro tutorial concluirá aquí para darnos algo de tiempo para explorar el gran número de posibilidades que nos ofrece Prophet. Para revisar juntos el código completo, he consolidado los fragmentos en este archivo Python. Además, puedes subir este notebook directamente a Colab y ejecutarlo tú mismo. ¡Cuéntame qué tal te ha funcionado!

Conclusión

Prophet es una potente herramienta para predecir valores futuros en datos de series temporales, especialmente cuando tus datos tienen patrones repetitivos como ciclos mensuales o anuales. Es fácil de usar y puede proporcionar rápidamente predicciones precisas para tus datos específicos. Sin embargo, es esencial ser consciente de sus limitaciones. Si tus datos no tienen un patrón claro o si hay cambios significativos que el modelo no haya visto antes, es posible que Prophet no funcione de forma óptima. Comprender estas limitaciones es crucial para utilizar la herramienta con sensatez.

La buena noticia es que es muy recomendable experimentar con Prophet en tus conjuntos de datos. Cada conjunto de datos es único, y ajustar la configuración y probar diferentes enfoques puede ayudarte a descubrir lo que funciona mejor para tu situación específica. Así pues, sumérgete, explora y mira cómo Prophet puede mejorar tus previsiones de series temporales.

References

[1] Shumway, Robert H.; Stoffer, David S. (2017): Time Series Analysis and Its Applications. Cham: Springer International Publishing.

[2] Brownlee, Jason (2017): Introduction to Time Series Forecasting With Python

[3] Rafferty, Greg (2021): Forecasting Time Series Data with Facebook Prophet

[4] https://facebook.github.io/prophet/docs/quick_start.html

The post Primeros pasos en la predicción de series temporales de datos con Facebook Prophet first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/primeros-pasos-en-prediccion-de-series-temporales-de-datos-con-facebook-prophet/feed/ 0
Long context LLM’s para tareas complejas: Desbloqueo de capacidades con recuperación selectiva https://desa.planetachatbot.com/llms-de-contexto-largo-para-tareas-complejas-desbloqueo-de-capacidades-con-recuperacion-selectiva/?utm_source=rss&utm_medium=rss&utm_campaign=llms-de-contexto-largo-para-tareas-complejas-desbloqueo-de-capacidades-con-recuperacion-selectiva https://desa.planetachatbot.com/llms-de-contexto-largo-para-tareas-complejas-desbloqueo-de-capacidades-con-recuperacion-selectiva/#respond Tue, 30 Apr 2024 06:00:06 +0000 https://desa.planetachatbot.com/?p=17553 El desarrollo de LLM como Gemini 1.5 Pro, con ventanas de contexto sin precedentes de hasta un millón de tokens, ha generado gran expectación por sus posibles aplicaciones en ámbitos que manejan gran cantidad de información. Algunos ejemplos son el análisis de documentos jurídicos, la síntesis de conocimientos en múltiples artículos científicos y la comprensión […]

The post Long context LLM’s para tareas complejas: Desbloqueo de capacidades con recuperación selectiva first appeared on Planeta Chatbot.

]]>
El desarrollo de LLM como Gemini 1.5 Pro, con ventanas de contexto sin precedentes de hasta un millón de tokens, ha generado gran expectación por sus posibles aplicaciones en ámbitos que manejan gran cantidad de información. Algunos ejemplos son el análisis de documentos jurídicos, la síntesis de conocimientos en múltiples artículos científicos y la comprensión de libros enteros para la escritura creativa o el análisis literario. Con unas capacidades de contexto tan amplias, hay grandes esperanzas de que los LLM’s puedan ingerir y razonar sobre fuentes de información extensas en su totalidad.

Sin embargo, no basta con ampliar la longitud de los contextos.

A pesar de los impresionantes tamaños de las ventanas de contexto, cada vez son más las investigaciones que revelan limitaciones críticas en la capacidad de los LLM actuales para aprovechar realmente estos contextos ampliados de forma eficaz. El simple aumento del tamaño de los modelos y de la longitud de los contextos no se traduce automáticamente en una mejora del rendimiento en tareas que requieren una comprensión y un razonamiento profundos en contextos extensos. Varios estudios clave han puesto de manifiesto estas deficiencias:

  1. Las pruebas de rendimiento como BABILong han demostrado que incluso los modelos más avanzados, como GPT-4, tienen dificultades para recordar y utilizar con precisión información clave cuando ésta se encuentra en contextos extensos de hasta 128.000 caracteres. Los estudios revelaron que el rendimiento de los modelos depende en gran medida del 25% inicial del contexto, lo que sugiere una incapacidad para procesar y utilizar plenamente la información distribuida en secuencias largas.
  2. Efectos del orden en el razonamiento multipaso largo
    La investigación ha demostrado que el orden de la información en contextos de entrada largos puede afectar significativamente a la capacidad de razonamiento de los LLM en tareas lógicas multipaso. Por ejemplo, la precisión del GPT-4 en tareas de razonamiento lógico puede disminuir hasta un 30% cuando se reordenan las premisas, a pesar de que la tarea de razonamiento subyacente y las conclusiones permanecen inalteradas. Estos efectos del orden se agravan a medida que aumenta la complejidad del razonamiento con contextos más largos que contienen información que distrae.
  3. Degradación en el aprendizaje en contexto prolongado. Un enfoque popular con los LLM es el «few – shots learning», en el que los modelos se condicionan a una secuencia de ejemplos para aprender una nueva tarea. Sin embargo, los estudios han revelado una fuerte degradación del rendimiento cuando este aprendizaje en contexto implica secuencias de más de unos pocos miles de tokens, a pesar de que los LLM tienen ventanas de contexto mucho mayores. Los modelos tienen dificultades para aprovechar y aprender eficazmente de las extensas demostraciones repartidas en contextos largos.

Degradación en el aprendizaje en contexto prolongado

Uno de los enfoques más utilizados con modelos lingüísticos de gran tamaño es el «few-shots learning» o el aprendizaje en contexto, en el que los modelos se condicionan a una secuencia de ejemplos para aprender y realizar una nueva tarea de una manera eficiente desde el punto de vista de los datos. Sin embargo, un estudio reciente titulado «Long-context LLMs Struggle with Long In-context Learning» ha revelado las limitaciones críticas de los LLM actuales cuando este paradigma de aprendizaje en contexto implica secuencias que abarcan miles de tokens y más.

Los investigadores introdujeron un nuevo punto de referencia denominado LongICLBench para evaluar sistemáticamente el rendimiento de los LLM en tareas extremas de clasificación de textos con múltiples etiquetas que se basan en largas demostraciones en contexto que abarcan diversos conjuntos de datos y miles de etiquetas únicas. Probaron exhaustivamente 13 LLM’s de última generación, incluidos GPT-4, PaLM y otros modelos comerciales y de código abierto, en tareas con longitudes de contexto que oscilaban entre 2.000 y 50.000 tokens.

Los resultados pusieron de manifiesto deficiencias notables en la capacidad de los LLM para aprovechar el aprendizaje en contexto ampliado a lo largo de secuencias largas:

  1. Aunque los LLM funcionaron relativamente bien en tareas más sencillas con demostraciones más cortas de 2.000/3.000 tokens, su precisión cayó en picado en tareas más complejas que requerían demostraciones más largas de más de 10.000 tokens en contexto que abarcaban distribuciones completas de etiquetas.
  2. En el conjunto de datos más difícil, «Discovery», con 174 etiquetas, incluso modelos como GPT-4 fracasaron por completo cuando se les presentaron más de 10.000 contextos de tokens que ilustraban todos los ejemplos de etiquetas antes de las consultas.
  3. El análisis reveló que los LLM tenían dificultades para conectar y razonar sobre ejemplos de etiquetas distribuidos en los largos contextos de demostración de varias rondas, y no lograban establecer asociaciones distantes.
  4. El aumento de la escala del modelo no contribuyó a mitigar estos problemas, ya que tanto los modelos 7B como los más grandes mostraron tendencias similares de degradación del rendimiento en tareas largas de aprendizaje en contexto.

Los investigadores plantearon la hipótesis de que, si bien los LLM destacan en el procesamiento de contextos locales, sus arquitecturas de autoatención se enfrentan a cuellos de botella a la hora de mantener mapeados coherentes a lo largo de secuencias ultralargas durante el condicionamiento de «few shots» sobre distribuciones complejas.

Este estudio subraya que no basta con escalar la longitud de los contextos, sino que pueden ser necesarias nuevas innovaciones arquitectónicas, como módulos de memoria explícita o atenciones dispersas, para mejorar el razonamiento de los LLM en demostraciones contextuales ampliadas con múltiples ejemplos, cruciales en ámbitos como el análisis jurídico.

El LongICLBench pone de relieve un área clave de investigación futura para liberar todo el potencial de los LLM en el «few shots learning» sobre contextos largos de diversas fuentes. La superación de estas limitaciones podría ser fundamental para una comprensión robusta de contextos extensos y sistemas de generación mejorados para la recuperación.

Retos y requisitos para aprovechar los Long Context LLMs

Aunque estas limitaciones puedan parecer desalentadoras, en realidad arrojan luz sobre los retos y requisitos clave que deben abordarse para aprovechar todo el potencial de los LLM en aplicaciones complejas de contexto largo o long context.

En lugar de aumentar indiscriminadamente la longitud de los contextos, cada vez está más claro que es crucial una recuperación de información más específica y una representación estructurada de la información relevante. No basta con proporcionar más contexto: los modelos necesitan orientación para aislar los elementos precisos de información pertinentes para la tarea en cuestión, filtrando al mismo tiempo los contenidos que distraen.

Combinación de LLM con representaciones estructuradas del conocimiento. Los métodos tradicionales de recuperación de la información basados únicamente en la relevancia textual pueden resultar inadecuados para el razonamiento complejo y multipaso en contextos extensos. Las representaciones estructuradas del conocimiento, como los grafos de conocimiento, pueden proporcionar sesgos inductivos que se ajusten mejor a los patrones de razonamiento subyacentes y codificar las relaciones semánticas de forma más transparente que el texto en bruto.

Cambios de paradigma: Del escalado al razonamiento aumentado. En última instancia, para seguir avanzando en el aprovechamiento de contextos extensos con los LLM probablemente se necesiten cambios de paradigma que vayan más allá del simple aumento de las ventanas de contexto y el tamaño de los modelos. Se necesitan nuevas arquitecturas que combinen la flexibilidad y la amplia cobertura de los LLM con capacidades de razonamiento basado en principios sobre representaciones estructuradas del conocimiento.

Recuperación selectiva en lugar de ingestión exhaustiva del contexto

Para aprovechar al máximo el potencial de las grandes ventanas de contexto, lo que se necesita es una recuperación más selectiva y una representación estructurada de sólo la información más pertinente para una tarea determinada. En lugar de abrumar a los LLM con contextos exhaustivos, necesitan orientación en forma de:

  1. Recuperación precisa de hechos, pruebas y conocimientos clave necesarios para razonar sobre la tarea.
  2. Representaciones estructuradas que destacan la relevancia y las relaciones entre la información recuperada.
  3. Filtrado del ruido y los distractores que podrían desviar la atención del LLM.

Al proporcionar a los LLM un contexto cuidadosamente elaborado y organizado, específico para los requisitos de la tarea, pueden superar limitaciones como el escaso recuerdo de la información relevante y la vulnerabilidad a los efectos de orden/premisa.

El caso de la generación aumentada por recuperación (RAG)

Esta necesidad de recuperación y representación específicas refuerza los argumentos a favor de los marcos de recuperación y generación mejorada (RAG). Los sistemas RAG combinan dos componentes:

  1. Un módulo de recuperación neuronal que identifica y extrae información relevante de un amplio corpus para servir de contexto a un modelo lingüístico.
  2. Un modelo lingüístico generativo que toma el contexto recuperado para generar resultados como responder a consultas, redactar resúmenes o participar en razonamientos de varios pasos.

Al delegar la recuperación de información pertinente en un módulo especializado, los marcos RAG pueden proporcionar a los LLM contextos centrados y adaptados a la tarea actual. De este modo, se evita que el LLM se atasque con un exceso de información irrelevante en contextos exhaustivos.

Limitaciones de la actual RAG sobre la relevancia textual

Sin embargo, los métodos tradicionales de RAG que se basan únicamente en la recuperación de información a partir de señales de relevancia textual pueden seguir siendo insuficientes para soportar razonamientos complejos de varios pasos en contextos largos. La similitud textual sólo capta las asociaciones superficiales y no representa la semántica, las relaciones y la lógica subyacentes necesarias para «unir los puntos» de forma eficaz en el razonamiento.

Para que el razonamiento en contextos amplios sea realmente sólido, los marcos de RAG deben ir más allá de la recuperación textual e incorporar representaciones estructuradas del conocimiento que puedan restringir y andamiar el proceso de razonamiento de los LLM.

Representaciones estructuradas del conocimiento para el razonamiento

Las representaciones estructuradas del conocimiento, como los grafos de conocimiento, ofrecen una solución prometedora. Los grafos de conocimiento modelan la información como entidades/conceptos y sus interrelaciones siguiendo ontologías/esquemas formales. Esta estructura de representación ofrece varias ventajas clave:

  • Relaciones semánticas: en lugar de asociaciones textuales ambiguas, las relaciones entre conceptos se definen formalmente (por ejemplo, isA, partOf, locatedAt).
  • Posibilidades de razonamiento: la estructura del grafo codifica de forma natural vías lógicas para encadenar hechos y recorrer conexiones con el fin de obtener información.
  • Conocimiento externo: los grafos de conocimiento del mundo real, como Wikidata, proporcionan un amplio conocimiento externo curado para aumentar los contextos de recuperación.
  • Algoritmos de grafos: la importancia de nodos y aristas, la extracción de subgrafos, la predicción de enlaces y otros algoritmos de grafos pueden priorizar y ampliar los contextos de razonamiento.

Si se amplían los marcos RAG para recuperar y operar sobre grafos de conocimiento estructurados en lugar de sólo sobre texto, se podría proporcionar a los LLM contextos que codifiquen de forma transparente la semántica, las restricciones y los sesgos inductivos para guiar mejor el razonamiento sobre contextos largos con menos ruido.

En esencia, la recuperación selectiva de representaciones de conocimiento estructurado podría ser la clave para que los LLM aprovechen al máximo sus capacidades de gran contexto en tareas que requieran un razonamiento robusto en varios pasos y la síntesis de conocimiento a partir de diversas fuentes. Es probable que las soluciones fusionen la amplia cobertura de los LLM con los conocimientos de la representación del conocimiento y el razonamiento automatizado. Este paradigma estructurado de RAG representa una dirección prometedora para maximizar la comprensión de contextos largos en los LLM.

Cambio de paradigma: del escalado al razonamiento aumentado

Las limitaciones señaladas ponen de manifiesto que para seguir avanzando en la IA de contexto amplio no basta con aumentar las ventanas de contexto y el tamaño de los modelos. Se necesitan nuevos paradigmas que combinen grandes modelos lingüísticos con capacidades de razonamiento basados en principios sobre representaciones estructuradas.

Esto podría implicar aumentar los LLM generativos con módulos especializados de «razonamiento» que intercalen la recuperación, el razonamiento en varios pasos y la generación de una manera interpretable. Tomar prestadas ideas de campos como la representación del conocimiento y el razonamiento automatizado podría dar resultados.

Esencialmente, el camino a seguir probablemente combine la flexibilidad y la amplia cobertura de los grandes modelos lingüísticos con la estructura, la transparencia y las posibilidades de composición de los sistemas de razonamiento simbólico. Sólo mediante arquitecturas unificadas de este tipo podremos desarrollar sistemas de IA capaces de comprender en profundidad y razonar sobre entornos ricos en información a gran escala.

Esta nueva frontera en la intersección de los grandes modelos lingüísticos y el razonamiento estructurado está repleta de oportunidades para la innovación. Aunque la ampliación de las longitudes de contexto ha dado el pistoletazo de salida, para liberar todo el potencial de la IA de contexto largo será necesario adoptar la recuperación y la representación inteligentes. Las soluciones darán forma a asistentes de IA fiables, transparentes y robustos que puedan navegar por fin por nuestros cada vez más complejos entornos de información.

The post Long context LLM’s para tareas complejas: Desbloqueo de capacidades con recuperación selectiva first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/llms-de-contexto-largo-para-tareas-complejas-desbloqueo-de-capacidades-con-recuperacion-selectiva/feed/ 0
Desambiguación: Uso del contexto dinámico para elaborar sugerencias eficaces de preguntas RAG https://desa.planetachatbot.com/desambiguacion-uso-contexto-dinamico-para-elaborar-sugerencias-eficaces-de-preguntas-rag/?utm_source=rss&utm_medium=rss&utm_campaign=desambiguacion-uso-contexto-dinamico-para-elaborar-sugerencias-eficaces-de-preguntas-rag https://desa.planetachatbot.com/desambiguacion-uso-contexto-dinamico-para-elaborar-sugerencias-eficaces-de-preguntas-rag/#respond Thu, 25 Apr 2024 06:00:29 +0000 https://desa.planetachatbot.com/?p=17483 Este enfoque recuerda a una técnica inicialmente aplicada por IBM Watson denominada desambiguación. Se trata de responder a una entrada ambigua del usuario con cinco o menos opciones entre las que elegir. De este modo, el usuario puede realizar la desambiguación por sí mismo y el sistema aprende de ella. Este enfoque también resuelve el […]

The post Desambiguación: Uso del contexto dinámico para elaborar sugerencias eficaces de preguntas RAG first appeared on Planeta Chatbot.

]]>
Este enfoque recuerda a una técnica inicialmente aplicada por IBM Watson denominada desambiguación. Se trata de responder a una entrada ambigua del usuario con cinco o menos opciones entre las que elegir. De este modo, el usuario puede realizar la desambiguación por sí mismo y el sistema aprende de ella.

Este enfoque también resuelve el problema del lienzo en blanco, en el que el usuario no sabe cuál es el ámbito de la interfaz y acaba haciendo preguntas exploratorias ambiguas.

Así, en lugar de obligar al usuario a refinar continuamente sus preguntas mientras recibe respuestas inadecuadas, la interfaz de usuario conversacional toma la iniciativa de desambiguar la conversación.

El generador está diseñado para generar preguntas sugeridas que el agente puede responder, guiado por la consulta inicial del usuario (Fuente).

Framework propuesto

  1. El framework identifica los pasajes apropiados (contextos recuperados dinámicamente) basándose en la entrada inicial del usuario.
  2. El proceso está asistido por preguntas, respuestas y preguntas de sugerencia (generadas mediante few-shot dinámicos).
  3. Las preguntas de sugerencia se generan a partir de un contexto dinámico compuesto por contextos recuperados dinámicamente y ejemplos dinámicos.
  4. Al proporcionar preguntas de desambiguación por sugerencia, se alivia a los usuarios de la carga cognitiva que supone la formulación de preguntas.
  5. El objetivo fundamental de esta investigación es establecer la verdadera intención del usuario durante la interacción.
  6. Lo atractivo de esta solución es que se trata de un enfoque de bajos recursos.

Diálogos orientados a tareas

En la siguiente imagen se aborda un ejemplo de búsqueda de información orientada a una tarea. Un usuario necesita buscar información relacionada con una tarea concreta. Debido a la ambigüedad de la entrada y el perfil del usuario, el sistema de diálogo orientado a tareas debe hacer preguntas de aclaración/desambiguación para aclarar la intención del usuario y el perfil del usuario basándose en el conocimiento de la tarea para proporcionar la respuesta.

Desambiguación

A continuación, el paradigma System Ask orientado a tareas:

En conclusión

El objetivo de este estudio es reducir las respuestas de disculpa de la interfaz de usuario conversacional y mejorar la experiencia del usuario proporcionando sugerencias informadas del sistema.

Los Contextos Dinámicos generan preguntas de sugerencia contestables por el agente a través de:

  1. Ejemplos dinámicos de pocas tomas y
  2. Contextos recuperados dinámicamente.

A diferencia de las sugerencias tradicionales de pocos disparos, los ejemplos dinámicos de pocos disparos seleccionan dinámicamente tripletas contextualmente relevantes en función de las consultas del usuario, dando cabida a diversos formatos y estructuras de preguntas.


 Sígueme en LinkedIn para estar al día sobre la IA conversacional 

Actualmente soy el Evangelista Jefe @ HumanFirst. Exploro y escribo sobre todas las cosas en la intersección de la IA y el lenguaje; que van desde LLMs, Chatbots, Voicebots, marcos de desarrollo, espacios latentes centrados en datos y más.

The post Desambiguación: Uso del contexto dinámico para elaborar sugerencias eficaces de preguntas RAG first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/desambiguacion-uso-contexto-dinamico-para-elaborar-sugerencias-eficaces-de-preguntas-rag/feed/ 0