LLMs 需要连接到真实世界。LangChain4j 工具,结合 Apache Camel,使这变得容易。Camel 提供强大的集成,将您的LLM连接到任何服务或API。这使得您的AI能够与数据库、队列等进行交互,创建真正强大的应用程序。我们将探讨这一强大组合及其潜力。
设置开发环境
- Ollama: 提供一种在本地运行大型语言模型(LLMs)的方式。您可以在您的计算机上运行许多模型,如 LLama3、Mistral、CodeLlama 等,并获得完整的 CPU 和 GPU 支持。
- Visual Studio Code: 安装了 Kaoto、Java 和 Quarkus 插件。
- OpenJDK 21
- Maven
- Quarkus 3.17
- Quarkus Dev Services: 是 Quarkus 的一个功能,简化了依赖外部服务(如数据库、消息系统和其他资源)的应用程序的开发和测试。
您可以在以下GitHub存储库中下载完整的代码。
以下说明将在Visual Studio Code上执行:
1. 创建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. 添加langchain4j 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. 配置Ollama以运行Ollama LLM
打开application.properties文件并添加以下行:
#配置Ollama本地模型
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使用Ollama在本地运行LLM,并在后续步骤中为在Apache camel组件中使用的自动连线配置。
4. 使用Kaoto创建Apache Camel路由
在src/main/resources文件夹中创建一个名为route的新文件夹。
在src/main/resources/routes文件夹中创建一个名为route-main.camel.yaml的新文件,并在Visual Studio Code中打开Kaoto可视化编辑器。
单击按钮+新建,将创建新路由。
单击圆形箭头以替换定时器组件。
从目录中搜索并选择platform-http组件。
配置所需的platform-http属性:
- 将路径设置为值 /camel/chat
默认情况下,platform-http将在端口8080上提供服务。
在platform-http组件后的箭头中单击添加步骤图标。
在目录中搜索并选择langchain4j-tools组件。
配置所需的langchain4j-tools属性:
- 将工具 ID设置为值my-tools。
- 将标签设置为store(定义标签是为了将工具分组以与LLM一起使用)
必须处理用户输入消息以使其适用于langchain4j-tools组件,然后在platform-http组件后的箭头上单击添加步骤图标。
在目录中搜索并选择Process组件。
配置所需属性:
- 设置Ref为值createChatMessage。
该处理组件将使用您将在下一步中创建的createChatMessage方法。
5. 创建一个处理程序以将用户输入发送到LLM
在src/main/java文件夹中创建一个新的Java类,命名为Bindings.java。
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 {
// 路由在yaml文件中加载。
}
@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 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);
}
};
}
}
这个类帮助创建一个Camel处理器来将用户输入转换为可以在路由中处理langchain4j组件的对象。它还为LLM提供使用工具的上下文,并解释Agent的任务。
6. 创建Apache Camel工具以与LLM一起使用
在src/main/resources/routes文件夹中创建一个新文件,命名为route-tool-products.camel.yaml, 并在Visual Studio Code中打开Kaoto可视化编辑器。
点击 +新建按钮,将创建一个新路由。
点击圆形箭头以替换计时器组件。
在目录中搜索并选择langchain4j-tools组件。
配置langchain4j-tools,点击全部选项卡并搜索端点属性。
- 将工具 ID设置为值productsbycategoryandcolor。
- 将标签设置为与主路由中相同的值store。
- 将描述设置为值查询数据库中的类别和颜色产品(工具的简要描述)。
添加工具将使用的参数:
- 名称:类别,值:字符串
- 名称:颜色,值:字符串
LLM 将为工具分配这些参数,并通过标头传递。
添加 SQL 组件以查询数据库,然后在langchain4j-tools组件后点击添加步骤。
搜索并选择SQL 组件。
配置必需的 SQL 属性:
- 使用以下值进行查询。
Select name, description, category, size, color, price, stock from products where Lower(category)= Lower (:#category) and Lower(color) = Lower(:#color)
处理要在查询中使用的参数,然后添加Convert Header 组件以将参数转换为正确的对象类型。
在langchain4j-tools后点击添加步骤按钮,搜索并选择目录中的Convert Header To转换。
为组件配置必需属性:
- 名称设为 category
- 类型设为 String
重复以下步骤并设置如下数值:
- 名称设为 color
- 类型设为 String
最终路由如下:
最后,需要将查询结果转换为LLM可处理的对象;在此示例中,将其转换为 JSON 格式。
在 SQL 组件后点击 添加步骤按钮,并添加 Marshal 组件。
为 Marshal 配置数据格式属性,并从列表中选择 JSON。
7. 为 PostgreSQL 配置 Quarkus Dev 服务
添加 Quarkus 扩展以提供 PostgreSQL 用于开发目的,在终端中运行以下命令。
./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-jdbc-postgresql"
打开 application.properties 并添加以下行:
#为 Postgresql 配置 devservices
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
最后,创建用于加载数据库的 SQL 脚本。
在 src/main/resources 中创建名为 db 的文件夹,然后在该文件夹中创建名为 schema-init.sql 的文件,并添加以下内容。
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. 将我们的路由包含到 Quarkus 项目中以加载
Camel Quarkus 支持使用多种特定领域语言(DSL)定义 Camel 路由。
还可以包含yaml DSL路由,只需在application.properties文件中添加以下行。
# 要加载的路由
camel.main.routes-include-pattern = routes/*.yaml
这将加载src/main/resources/routes文件夹中的所有路由。
9. 测试应用程序
使用Maven运行应用程序,在Visual Studio Code中打开终端,并运行以下命令。
mvn quarkus:dev
一旦启动,Quarkus调用Ollama并在本地运行您的LLM,打开一个终端,并通过以下命令进行验证。
ollama ps
NAME ID SIZE PROCESSOR UNTIL
qwen2.5:0.5b a8b0c5157701 1.4 GB 100% GPU 4 minutes from now
此外,Quarkus创建一个运行PostgreSQL的容器,并创建一个数据库和模式。您可以使用psql
命令进行连接。
psql -h localhost -p 5432 -U quarkus -d store
并查询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)
要测试应用程序,请向localhost:8080/camel/chat发送一个带有纯文本正文输入的POST请求,请求某个产品。
LLM可能出现了幻觉。请尝试稍微修改您的请求后再试一次。
您可以看到LLM如何使用该工具,并从数据库中获取信息,使用提供的自然语言请求。LLM识别参数并将它们发送给工具。如果查看请求日志,您可以找到LLM用于创建答案的工具和参数。
结论
您已经探索了如何利用Apache Camel和LangChain4j组件在集成流程中发挥LLM的强大功能。我们已经看到,这种组合使您能够将强大的语言模型无缝集成到现有的Camel路由中,从而使您能够构建能够理解、生成和与人类语言交互的复杂应用程序。
Source:
https://dzone.com/articles/powering-llms-with-apache-camel-and-langchain4j