Existe un concepto conocido como «tools» o «herramientas». Permite al LLM llamar, cuando sea necesario, a una o más herramientas disponibles, normalmente definidas por el desarrollador. Una herramienta puede ser cualquier cosa: una búsqueda en la web, una llamada a una API externa, la ejecución de un fragmento de código específico, etc. En realidad, los LLM no pueden llamar a la herramienta ellos mismos, sino que expresan la intención de llamar a una herramienta específica en su respuesta (en lugar de responder en texto plano). Nosotros, como desarrolladores, debemos ejecutar esta herramienta con los argumentos proporcionados e informar de los resultados de la ejecución de la herramienta.
Las herramientas LangChain4j, combinadas con Apache Camel, facilitan esta tarea. Camel proporciona una integración robusta, conectando tu LLM a cualquier servicio o API. Esto permite a tu IA interactuar con bases de datos, colas y más, creando aplicaciones realmente potentes. Exploraremos esta poderosa combinación y su potencial.
En esta publicación
Configuración del entorno de desarrollo.
- Ollama. Proporciona una forma de ejecutar localmente Modelos (LLM). Puede ejecutar muchos modelos como LLama3, Mistral, CodeLlama y muchos otros en local, con soporte completo de CPU y GPU.
- Visual Studio Code. Con los plugins Kaoto, Java y Quarkus instalados.
- OpenJDK 21
- Maven
- Quarkus 3.17
- Quarkus Dev Services. Característica de Quarkus que simplifica el desarrollo y prueba de aplicaciones el desarrollo y prueba de aplicaciones que dependen de servicios externos como bases de datos, sistemas de mensajería y otros recursos.
Puede descargar el código completo en el siguiente repositorio de Github.
Las siguientes instrucciones se ejecutarán en Visual Studio Code.
1. Creando el proyecto de Quarkus.
mvn io.quarkus:quarkus-maven-plugin:3.17.6:create \ -DprojectGroupId=dev.mikeintoch \ -DprojectArtifactId=camel-agent-tools \ -Dextensions="camel-quarkus-core,camel-quarkus-langchain4j-chat,camel-quarkus-langchain4j-tools,camel-quarkus-platform-http,camel-quarkus-yaml-dsl"
2. Añadir extensiones langchain4j de Quarkus.
./mvnw quarkus:add-extension -Dextensions="io.quarkiverse.langchain4j:quarkus-langchain4j-core:0.22.0" ./mvnw quarkus:add-extension -Dextensions="io.quarkiverse.langchain4j:quarkus-langchain4j-ollama:0.22.0"
3. Configura Ollama para ejecutar su LLM.
Abrir el archivo application.properties y agregar las siguientes lineas:
#Configure Ollama local model quarkus.langchain4j.ollama.chat-model.model-id=qwen2.5:0.5b quarkus.langchain4j.ollama.chat-model.temperature=0.0 quarkus.langchain4j.ollama.log-requests=true quarkus.langchain4j.log-responses=true quarkus.langchain4j.ollama.timeout=180s
** Quarkus utiliza Ollama para ejecutar llm localmente y también conecta la configuración para el uso en los componentes de Apache Camel para los siguientes pasos. **
4. Creando su ruta Apache Camel utilizando Kaoto.
Crear un nuevo directorio nombrado route dentro del directorio src/main/resources.
Crear un nuevo archivo dentro de la carpeta src/main/resources/routes y nómbralo route-main.camel.yaml. Visual Studio Code abrirá el editor visual de Kaoto.
Haga clic en el botón +New y se creará una nueva ruta.
Haga clic en las flechas circulares para sustituir el componente timer.
Busque y seleccione en el catálogo el componente plataform-http.
Configurar las propiedades requeridas del componente plataform-http:
- Establezca el propiedad Path con el valor /camel/chat
Por defecto platform-http servirá en el puerto 8080.
Haga clic en el Icono Add Step en la flecha después del componente plataform-http.
Busque y seleccione el componente langhchain4j-tools en el catálogo.
Configure las propiedades requeridas de langhchain4j-tools:
- Establecer Tool Id con el valor my-tools.
- Establecer Tags con store (Definir tags es para agrupar las herramientas a utilizar con el LLM).
Se debe procesar el mensaje de entrada del usuario para que el componente langchain4j-tools sea capaz de manejar. A continuación, haga clic en el icono Add Step en la flecha después del component plataform-http.
Busque y seleccione el componente Process en el catálogo.
Configure las propiedades requeridas:
- Establece Ref con el valor createChatMessage.
** El componente de Process utilizará el método createChatMessage que se va crear en el siguiente paso. **
5. Crear Proceso para enviar la entrada del usuario al LLM.
Crear una nueva clase Java en la carpeta src/main/java llamada Bindings.java con el siguiente contenido
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.HashMap; import org.apache.camel.BindToRegistry; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; import dev.langchain4j.data.message.ChatMessage; import dev.langchain4j.data.message.SystemMessage; import dev.langchain4j.data.message.UserMessage; public class Bindings extends RouteBuilder{ @Override public void configure() throws Exception { // Routes are loading in yaml files. } @BindToRegistry(lazy=true) public static Processor createChatMessage(){ return new Processor() { public void process(Exchange exchange) throws Exception{ String payload = exchange.getMessage().getBody(String.class); List<ChatMessage> messages = new ArrayList<>(); String systemMessage = """ You are an intelligent store assistant. Users will ask you questions about store product. Your task is to provide accurate and concise answers. In the store have shirts, dresses, pants, shoes with no specific category %s If you are unable to access the tools to answer the user's query, Tell the user that the requested information is not available at this time and that they can try again later. """; String tools = """ You have access to a collection of tools You can use multiple tools at the same time Complete your answer using data obtained from the tools """; messages.add(new SystemMessage(systemMessage.formatted(tools))); messages.add(new UserMessage(payload)); exchange.getIn().setBody(messages); } }; } }
** Esta clase ayuda a crear Camel Processor para transformar la entrada del usuario a un objeto que pueda manejar el componentes langchain4j en la ruta.
También sirve para dar contexto al LLM para el uso de las tools y cual es la tarea para el Agente **.
6. Creación de herramientas Apache Camel para su uso con LLM.
Crear un nuevo archivo en la carpeta src/main/resources/routes con el nombre route-tool-products.camel,yaml y Visual Studio Code abrirá el editor visual Kaoto.
Haga clic en el botón +New y se creará una nueva ruta de Camel.
Haga clic en las flechas circulares para sustituir el componente de timer.
Buscar y seleccionar en el catálogo el componente langchain4j-tools.
Configurar langchain4j-tools haga clic en la pestaña All y buscar Endpoint properties.
- Establecer toolId con el valor productosporcategoríaycolor.
- Establecer Tags with store (Lo mismo que en la ruta principal).
- Establecer Description con el valor Query database products by category and color (Una breve descripción de la herramienta).
Añada los parámetros que utilizará la herramienta con los siguientes valores:
NAME | VALUE |
category | string |
color | string |
Quedando de la siguiente forma:
** Estos parámetros serán asignados por el LLM para su uso en la herramienta y se pasan a través de los headers**.
Añada el componente SQL para consultar la base de datos y haga clic en Add Step después del componente langchain4j-tools.
Buscar y seleccionar sql component en el catalogo.
Configure las propiedades sql requeridas:
- Query con el siguiente valor.
Select name, description, category, size, color, price, stock from products where Lower(category)= Lower (:#category) and Lower(color) = Lower(:#color)
Para manejar los parámetros en la consulta añada el componente Convert Header para transformar los parámetros a un tipo de objeto correcto.
Haga clic en el botón Add Step después de langchain4j-tools, busque y seleccione Convert Header To en el catálogo.
Configure las propiedades requeridas para el componente:
- Name con el valor category
- Type con el valor String
Repita los pasos con los valores siguientes:
- Name con el valor color
- Type con el valor String
Como resultado, este es el aspecto de la ruta
Finalmente necesita transformar el resultado de la consulta a un objeto que el LLM pueda manejar, en este ejemplo usará una transformación a JSON.
Haga clic en el botón Add Step después de SQL Component, y añada el componente Marshal
Configure las propiedades del formato de datos para el Marshal, seleccione JSon de la lista.
7. Configurar Quarkus Dev Services para PostgreSQL.
Añada la extensión de Quarkus para proporcionar PostgreSQL para propósitos de desarrollo, ejecute el siguiente comando en el terminal.
./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-jdbc-postgresql"
Abra application.properties y añada las siguientes líneas
#Configuring devservices for Postgresql quarkus.datasource.db-kind=postgresql quarkus.datasource.devservices.port=5432 quarkus.datasource.devservices.init-script-path=db/schema-init.sql quarkus.datasource.devservices.db-name=store
Finalmente crear nuestro script sql para cargar la base de datos.
Cree una carpeta llamada db en src/main/resources y en esta carpeta cree un archivo llamado schema-init.sql con el siguiente contenido.
DROP TABLE IF EXISTS products; CREATE TABLE IF NOT EXISTS products ( id SERIAL NOT NULL, name VARCHAR(100) NOT NULL, description varchar(150), category VARCHAR(50), size VARCHAR(20), color VARCHAR(20), price DECIMAL(10,2) NOT NULL, stock INT NOT NULL, CONSTRAINT products_pk PRIMARY KEY (id) ); INSERT INTO products (name, description, category, size, color, price, stock) VALUES ('Blue shirt', 'Cotton shirt, short-sleeved', 'Shirts', 'M', 'Blue', 29.99, 10), ('Black pants', 'Jeans, high waisted', 'Pants', '32', 'Black', 49.99, 5), ('White Sneakers', 'Sneakers', 'Shoes', '40', 'White', 69.99, 8), ('Floral Dress', 'Summer dress, floral print, thin straps.', 'Dress', 'M', 'Pink', 39.99, 12), ('Skinny Jeans', 'Dark denim jeans, high waist, skinny fit.', 'Pants', '28', 'Blue', 44.99, 18), ('White Sneakers', 'Casual sneakers, rubber sole, minimalist design.', 'Shoes', '40', 'White', 59.99, 10), ('Beige Chinos', 'Casual dress pants, straight cut, elastic waist.', 'Pants', '32', 'Beige', 39.99, 15), ('White Dress Shirt', 'Cotton shirt, long sleeves, classic collar.', 'Shirts', 'M', 'White', 29.99, 20), ('Brown Hiking Boots', 'Waterproof boots, rubber sole, perfect for hiking.', 'Shoes', '42', 'Brown', 89.99, 7), ('Distressed Jeans', 'Distressed denim jeans, mid-rise, regular fit.', 'Pants', '30', 'Blue', 49.99, 12);
8. Incluir nuestra Ruta para ser cargada por el proyecto de Quarkus.
Camel Quarkus admite varios lenguajes específicos de dominio (DSL) para definir rutas Camel.
También es posible incluir rutas DSL yaml añadiendo la siguiente línea en el archivo application.properties.
# routes to load camel.main.routes-include-pattern = routes/*.yaml
** Esto cargará todas las rutas en la carpeta src/main/resources/routes . **
9. Probar la aplicación.
Ejecute la aplicación utilizando Maven, abra un Terminal en Visual Studio Code y ejecute el siguiente comando.
mvn quarkus:dev
Una vez que se ha iniciado, Quarkus utiliza ollama y ejecutar localmente el llm, abra un terminal y verifique con el siguiente comando.
ollama ps NAME ID SIZE PROCESSOR UNTIL qwen2.5:0.5b a8b0c5157701 1.4 GB 100% GPU 4 minutes from now
También Quarkus con ayuda de Podman crea un contenedor que ejecuta postgresql, crea base de datos y esquema. Puede conectarse utilizando el comando psql.
psql -h localhost -p 5432 -U quarkus -d store
Y consulta la tabla de PRODUCTS.
store=# select * from products; id | name | description | category | size | color | price | stock ----+--------------------+----------------------------------------------------+----------+------+-------+-------+------- 1 | Blue shirt | Cotton shirt, short-sleeved | Shirts | M | Blue | 29.99 | 10 2 | Black pants | Jeans, high waisted | Pants | 32 | Black | 49.99 | 5 3 | White Sneakers | Sneakers | Shoes | 40 | White | 69.99 | 8 4 | Floral Dress | Summer dress, floral print, thin straps. | Dress | M | Pink | 39.99 | 12 5 | Skinny Jeans | Dark denim jeans, high waist, skinny fit. | Pants | 28 | Blue | 44.99 | 18 6 | White Sneakers | Casual sneakers, rubber sole, minimalist design. | Shoes | 40 | White | 59.99 | 10 7 | Beige Chinos | Casual dress pants, straight cut, elastic waist. | Pants | 32 | Beige | 39.99 | 15 8 | White Dress Shirt | Cotton shirt, long sleeves, classic collar. | Shirts | M | White | 29.99 | 20 9 | Brown Hiking Boots | Waterproof boots, rubber sole, perfect for hiking. | Shoes | 42 | Brown | 89.99 | 7 10 | Distressed Jeans | Distressed denim jeans, mid-rise, regular fit. | Pants | 30 | Blue | 49.99 | 12 (10 rows)
Para probar la aplicación, envíe una solicitud POST a localhost:8080/camel/chat con una entrada de cuerpo de texto sin formato, solicitando algún producto, a continuación un ejemplo.
** El LLM puede tenes alucinaciones. Por favor, inténtelo de nuevo modificando ligeramente su petición. **
Puede ver como el LLM utiliza la herramienta y obtiene información de la base de datos utilizando la petición proporcionando en lenguaje natural, el LLM identifica los parámetros enviados a la herramienta, si miras en el log sobre la petición puedes encontrar las herramientas y parámetros que el LLM está utilizando para crear la respuesta.
Conclusión
Ha explorado como aprovechar la potencia de los LLM en sus flujos de integración utilizando Apache Camel y el componente LangChain4j. Hemos visto cómo esta combinación le permite integrar sin problemas potentes modelos de lenguaje en sus rutas Camel existentes, lo que le permite construir aplicaciones inteligentes que pueden entender, generar e interactuar con el lenguaje natural.