This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-quarkus-examples.git
commit 1b2eefd2c1eec5bae4a7e836fa427a42bcc71ba2 Author: aldettinger <aldettin...@gmail.com> AuthorDate: Tue Oct 29 10:54:25 2024 +0100 Data extract switch to granite3 --- data-extract-langchain4j/README.adoc | 8 ++++---- .../src/main/resources/application.properties | 2 +- .../org/acme/extraction/OllamaTestResource.java | 15 ++++++++++++-- ..._chat-495066d1-9278-4e4b-b8f6-a1c2fa296779.json | 24 ---------------------- ..._chat-52961581-e5b1-4309-b62f-1c6e1e0008eb.json | 24 ---------------------- ..._chat-5c1f926c-0480-41e9-9ca7-a93e17919e99.json | 24 ---------------------- ..._chat-75e11d9e-fdc3-4873-847d-982daec53233.json | 24 ++++++++++++++++++++++ ..._chat-861b9f1b-91c6-4206-8c8b-7e393c33d16c.json | 24 ++++++++++++++++++++++ ..._chat-b837ed7e-cb2a-43f4-84a9-8522b0c4d34d.json | 24 ++++++++++++++++++++++ 9 files changed, 90 insertions(+), 79 deletions(-) diff --git a/data-extract-langchain4j/README.adoc b/data-extract-langchain4j/README.adoc index 00ea497..f0854e7 100644 --- a/data-extract-langchain4j/README.adoc +++ b/data-extract-langchain4j/README.adoc @@ -15,7 +15,7 @@ In this example, we'll convert those text conversations into Java Objects that c image::schema.png[] In order to achieve this extraction, we'll need a https://en.wikipedia.org/wiki/Large_language_model[Large Language Model (LLM)] that natively supports JSON output. -Here, we arbitrarily choose https://ollama.com/library/codellama[codellama] served through https://ollama.com/[ollama]. +Here, we choose https://ollama.com/library/granite3-dense[granite3-dense] served through https://ollama.com/[ollama] as it seems compute friendly and under Apache V2 license. In order to request inference to the served model, we'll use the high-level LangChain4j APIs like https://docs.langchain4j.dev/tutorials/ai-services[AiServices]. More precisely, we'll setup the https://docs.quarkiverse.io/quarkus-langchain4j/dev/index.html[Quarkus LangChain4j extension] to register an AiService bean. Finally, we'll invoke the AiService extraction method via the https://camel.apache.org/camel-quarkus/latest/reference/extensions/bean.html[Camel Quarkus bean extension] . @@ -26,7 +26,7 @@ Let's start a container to serve the LLM with Ollama, in a first shell type: [source,shell] ---- -docker run --rm -it -v cqex-data-extract-ollama:/root/.ollama -p 11434:11434 --name cqex-data-extract-ollama ollama/ollama:0.3.12 +docker run --rm -it -v cqex-data-extract-ollama:/root/.ollama -p 11434:11434 --name cqex-data-extract-ollama ollama/ollama:0.4.0-rc5 ---- After a moment, a log like below should be output: @@ -40,7 +40,7 @@ Then, download the codellama model, in a second shell type: [source,shell] ---- -docker exec -it cqex-data-extract-ollama ollama pull codellama +docker exec -it cqex-data-extract-ollama ollama pull granite3-dense ---- After a moment, log like below should be output: @@ -106,7 +106,7 @@ At the end, we are provided with a Plain Old Java Object (POJO) handling the ext "customerSatisfied": "true", "customerName": "Sarah London", "customerBirthday": "10 July 1986", - "summary": "Declare an accident on main vehicle and receive reimbursement for expenses." + "summary": "The customer, Sarah London, called to declare an accident on her main vehicle and was informed that all expenses related to the accident would be reimbursed." } ---- diff --git a/data-extract-langchain4j/src/main/resources/application.properties b/data-extract-langchain4j/src/main/resources/application.properties index 633c2db..da692fb 100644 --- a/data-extract-langchain4j/src/main/resources/application.properties +++ b/data-extract-langchain4j/src/main/resources/application.properties @@ -20,7 +20,7 @@ quarkus.banner.enabled = false # Configure Quarkus LangChain4j that handle interactions with the Large Language Model quarkus.langchain4j.ollama.base-url = http://localhost:11434 quarkus.langchain4j.ollama.timeout = 3m -quarkus.langchain4j.ollama.chat-model.model-id = codellama +quarkus.langchain4j.ollama.chat-model.model-id = granite3-dense quarkus.langchain4j.ollama.chat-model.format = json quarkus.langchain4j.ollama.chat-model.temperature = 0 # Uncomment lines below to log Ollama client requests and responses diff --git a/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java b/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java index b9cebd6..08ef690 100644 --- a/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java +++ b/data-extract-langchain4j/src/test/java/org/acme/extraction/OllamaTestResource.java @@ -23,10 +23,12 @@ import com.github.tomakehurst.wiremock.WireMockServer; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testcontainers.containers.Container.ExecResult; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.ollama.OllamaContainer; import static java.lang.String.format; +import static java.lang.System.currentTimeMillis; import static org.eclipse.microprofile.config.ConfigProvider.getConfig; @@ -34,7 +36,7 @@ public class OllamaTestResource implements QuarkusTestResourceLifecycleManager { private static final Logger LOG = LoggerFactory.getLogger(OllamaTestResource.class); - private static final String OLLAMA_IMAGE = "ollama/ollama:0.3.12"; + private static final String OLLAMA_IMAGE = "ollama/ollama:0.4.0-rc5"; private static final int OLLAMA_SERVER_PORT = 11434; private static final String MODE_MOCK = "mock"; @@ -84,7 +86,16 @@ public class OllamaTestResource implements QuarkusTestResourceLifecycleManager { String ollamaModelId = getConfig().getValue("quarkus.langchain4j.ollama.chat-model.model-id", String.class); - ollamaContainer.execInContainer("ollama", "pull", ollamaModelId); + ExecResult result = ollamaContainer.execInContainer("ollama", "pull", ollamaModelId); + long pullBegin = currentTimeMillis(); + while ((currentTimeMillis() - pullBegin < 10000) + && (result.getStderr() == null || !result.getStderr().contains("success"))) { + LOG.info("Will retry ollama pull after sleeping 250ms"); + + Thread.sleep(250); + + result = ollamaContainer.execInContainer("ollama", "pull", ollamaModelId); + } baseUrl = format(BASE_URL_FORMAT, ollamaContainer.getHost(), ollamaContainer.getMappedPort(OLLAMA_SERVER_PORT)); diff --git a/data-extract-langchain4j/src/test/resources/mappings/api_chat-495066d1-9278-4e4b-b8f6-a1c2fa296779.json b/data-extract-langchain4j/src/test/resources/mappings/api_chat-495066d1-9278-4e4b-b8f6-a1c2fa296779.json deleted file mode 100644 index ba1c2d3..0000000 --- a/data-extract-langchain4j/src/test/resources/mappings/api_chat-495066d1-9278-4e4b-b8f6-a1c2fa296779.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "id" : "495066d1-9278-4e4b-b8f6-a1c2fa296779", - "name" : "api_chat", - "request" : { - "url" : "/api/chat", - "method" : "POST", - "bodyPatterns" : [ { - "equalToJson" : "{\n \"model\" : \"codellama\",\n \"messages\" : [ {\n \"role\" : \"assistant\",\n \"content\" : \"{\\n\\\"customerSatisfied\\\": false,\\n\\\"customerName\\\": \\\"John Doe\\\",\\n\\\"customerBirthday\\\": \\\"2001-11-01\\\",\\n\\\"summary\\\": \\\"Insurance company failed to notify customer of automatic cancellation of full reimbursement option and only provided half reimbursement for accident.\\\"\\n}\"\n }, {\n \"role\" : \"user\",\n \"content\" : [...] - "ignoreArrayOrder" : true, - "ignoreExtraElements" : true - } ] - }, - "response" : { - "status" : 200, - "body" : "{\"model\":\"codellama\",\"created_at\":\"2024-08-28T16:54:19.439835677Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\": true,\\n\\\"customerName\\\": \\\"Kate Boss\\\",\\n\\\"customerBirthday\\\": \\\"1999-08-13\\\",\\n\\\"summary\\\": \\\"Customer was unable to find their insurance contract and had to go through a process of updating their name on the contract. The operator provided assistance throughout the process, ensuring that the cu [...] - "headers" : { - "Date" : "Wed, 28 Aug 2024 16:54:19 GMT", - "Content-Type" : "application/json; charset=utf-8" - } - }, - "uuid" : "495066d1-9278-4e4b-b8f6-a1c2fa296779", - "persistent" : true, - "insertionIndex" : 4 -} \ No newline at end of file diff --git a/data-extract-langchain4j/src/test/resources/mappings/api_chat-52961581-e5b1-4309-b62f-1c6e1e0008eb.json b/data-extract-langchain4j/src/test/resources/mappings/api_chat-52961581-e5b1-4309-b62f-1c6e1e0008eb.json deleted file mode 100644 index 9a626a0..0000000 --- a/data-extract-langchain4j/src/test/resources/mappings/api_chat-52961581-e5b1-4309-b62f-1c6e1e0008eb.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "id" : "52961581-e5b1-4309-b62f-1c6e1e0008eb", - "name" : "api_chat", - "request" : { - "url" : "/api/chat", - "method" : "POST", - "bodyPatterns" : [ { - "equalToJson" : "{\n \"model\" : \"codellama\",\n \"messages\" : [ {\n \"role\" : \"user\",\n \"content\" : \"Extract information about a customer from the text delimited by triple backticks: ```Operator: Hello, how may I help you ?\\nCustomer: Hello, I'm calling because I need to declare an accident on my main vehicle.\\nOperator: Ok, can you please give me your name ?\\nCustomer: My name is Sarah London.\\nOperator: Could you please give me your birth date ?\\nCustomer: 1 [...] - "ignoreArrayOrder" : true, - "ignoreExtraElements" : true - } ] - }, - "response" : { - "status" : 200, - "body" : "{\"model\":\"codellama\",\"created_at\":\"2024-08-28T16:52:55.508750951Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\": true,\\n\\\"customerName\\\": \\\"Sarah London\\\",\\n\\\"customerBirthday\\\": \\\"1986-07-10\\\",\\n\\\"summary\\\": \\\"Declare an accident on main vehicle and receive reimbursement for expenses.\\\"\\n}\"},\"done_reason\":\"stop\",\"done\":true,\"total_duration\":22737688834,\"load_duration\":848753776,\"prompt_eval_ [...] - "headers" : { - "Date" : "Wed, 28 Aug 2024 16:52:55 GMT", - "Content-Type" : "application/json; charset=utf-8" - } - }, - "uuid" : "52961581-e5b1-4309-b62f-1c6e1e0008eb", - "persistent" : true, - "insertionIndex" : 6 -} \ No newline at end of file diff --git a/data-extract-langchain4j/src/test/resources/mappings/api_chat-5c1f926c-0480-41e9-9ca7-a93e17919e99.json b/data-extract-langchain4j/src/test/resources/mappings/api_chat-5c1f926c-0480-41e9-9ca7-a93e17919e99.json deleted file mode 100644 index 9ed4cfe..0000000 --- a/data-extract-langchain4j/src/test/resources/mappings/api_chat-5c1f926c-0480-41e9-9ca7-a93e17919e99.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "id" : "5c1f926c-0480-41e9-9ca7-a93e17919e99", - "name" : "api_chat", - "request" : { - "url" : "/api/chat", - "method" : "POST", - "bodyPatterns" : [ { - "equalToJson" : "{\n \"model\" : \"codellama\",\n \"messages\" : [ {\n \"role\" : \"assistant\",\n \"content\" : \"{\\n\\\"customerSatisfied\\\": true,\\n\\\"customerName\\\": \\\"Sarah London\\\",\\n\\\"customerBirthday\\\": \\\"1986-07-10\\\",\\n\\\"summary\\\": \\\"Declare an accident on main vehicle and receive reimbursement for expenses.\\\"\\n}\"\n }, {\n \"role\" : \"user\",\n \"content\" : \"Extract information about a customer from the text delimited by trip [...] - "ignoreArrayOrder" : true, - "ignoreExtraElements" : true - } ] - }, - "response" : { - "status" : 200, - "body" : "{\"model\":\"codellama\",\"created_at\":\"2024-08-28T16:53:37.033889726Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\": false,\\n\\\"customerName\\\": \\\"John Doe\\\",\\n\\\"customerBirthday\\\": \\\"2001-11-01\\\",\\n\\\"summary\\\": \\\"Insurance company failed to notify customer of automatic cancellation of full reimbursement option and only provided half reimbursement for accident.\\\"\\n}\"},\"done_reason\":\"stop\",\"done\":true,\" [...] - "headers" : { - "Date" : "Wed, 28 Aug 2024 16:53:37 GMT", - "Content-Type" : "application/json; charset=utf-8" - } - }, - "uuid" : "5c1f926c-0480-41e9-9ca7-a93e17919e99", - "persistent" : true, - "insertionIndex" : 5 -} \ No newline at end of file diff --git a/data-extract-langchain4j/src/test/resources/mappings/api_chat-75e11d9e-fdc3-4873-847d-982daec53233.json b/data-extract-langchain4j/src/test/resources/mappings/api_chat-75e11d9e-fdc3-4873-847d-982daec53233.json new file mode 100644 index 0000000..9f95f7b --- /dev/null +++ b/data-extract-langchain4j/src/test/resources/mappings/api_chat-75e11d9e-fdc3-4873-847d-982daec53233.json @@ -0,0 +1,24 @@ +{ + "id" : "75e11d9e-fdc3-4873-847d-982daec53233", + "name" : "api_chat", + "request" : { + "url" : "/api/chat", + "method" : "POST", + "bodyPatterns" : [ { + "equalToJson" : "{\n \"model\" : \"granite3-dense\",\n \"messages\" : [ {\n \"role\" : \"assistant\",\n \"content\" : \"{\\n\\\"customerSatisfied\\\": true,\\n\\\"customerName\\\": \\\"Sarah London\\\",\\n\\\"customerBirthday\\\": \\\"1986-07-10\\\",\\n\\\"summary\\\": \\\"The customer, Sarah London, called to declare an accident on her main vehicle and was informed that all expenses related to the accident would be reimbursed.\\\"\\n}\"\n }, {\n \"role\" : \"user\",\n [...] + "ignoreArrayOrder" : true, + "ignoreExtraElements" : true + } ] + }, + "response" : { + "status" : 200, + "body" : "{\"model\":\"granite3-dense\",\"created_at\":\"2024-10-29T14:22:39.979850929Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\": false,\\n\\\"customerName\\\": \\\"John Doe\\\",\\n\\\"customerBirthday\\\": \\\"2001-11-01\\\",\\n\\\"summary\\\": \\\"The customer, John Doe, called to express dissatisfaction with the insurance company's reimbursement policy and was informed that the full reimbursement option had been automatically cancelled.\\\" [...] + "headers" : { + "Date" : "Tue, 29 Oct 2024 14:22:39 GMT", + "Content-Type" : "application/json; charset=utf-8" + } + }, + "uuid" : "75e11d9e-fdc3-4873-847d-982daec53233", + "persistent" : true, + "insertionIndex" : 5 +} \ No newline at end of file diff --git a/data-extract-langchain4j/src/test/resources/mappings/api_chat-861b9f1b-91c6-4206-8c8b-7e393c33d16c.json b/data-extract-langchain4j/src/test/resources/mappings/api_chat-861b9f1b-91c6-4206-8c8b-7e393c33d16c.json new file mode 100644 index 0000000..7829e7a --- /dev/null +++ b/data-extract-langchain4j/src/test/resources/mappings/api_chat-861b9f1b-91c6-4206-8c8b-7e393c33d16c.json @@ -0,0 +1,24 @@ +{ + "id" : "861b9f1b-91c6-4206-8c8b-7e393c33d16c", + "name" : "api_chat", + "request" : { + "url" : "/api/chat", + "method" : "POST", + "bodyPatterns" : [ { + "equalToJson" : "{\n \"model\" : \"granite3-dense\",\n \"messages\" : [ {\n \"role\" : \"assistant\",\n \"content\" : \"{\\n\\\"customerSatisfied\\\": false,\\n\\\"customerName\\\": \\\"John Doe\\\",\\n\\\"customerBirthday\\\": \\\"2001-11-01\\\",\\n\\\"summary\\\": \\\"The customer, John Doe, called to express dissatisfaction with the insurance company's reimbursement policy and was informed that the full reimbursement option had been automatically cancelled.\\\"\\n}\"\n [...] + "ignoreArrayOrder" : true, + "ignoreExtraElements" : true + } ] + }, + "response" : { + "status" : 200, + "body" : "{\"model\":\"granite3-dense\",\"created_at\":\"2024-10-29T14:22:53.209341109Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\": true,\\n\\\"customerName\\\": \\\"Kate Boss\\\",\\n\\\"customerBirthday\\\": \\\"1999-08-13\\\",\\n\\\"summary\\\": \\\"The customer, Kate Boss, called to inquire about a proof of insurance after an accident and the operator helped her find her contract and arranged for the proof to be sent to the police station.\\\ [...] + "headers" : { + "Date" : "Tue, 29 Oct 2024 14:22:53 GMT", + "Content-Type" : "application/json; charset=utf-8" + } + }, + "uuid" : "861b9f1b-91c6-4206-8c8b-7e393c33d16c", + "persistent" : true, + "insertionIndex" : 4 +} \ No newline at end of file diff --git a/data-extract-langchain4j/src/test/resources/mappings/api_chat-b837ed7e-cb2a-43f4-84a9-8522b0c4d34d.json b/data-extract-langchain4j/src/test/resources/mappings/api_chat-b837ed7e-cb2a-43f4-84a9-8522b0c4d34d.json new file mode 100644 index 0000000..ddfc598 --- /dev/null +++ b/data-extract-langchain4j/src/test/resources/mappings/api_chat-b837ed7e-cb2a-43f4-84a9-8522b0c4d34d.json @@ -0,0 +1,24 @@ +{ + "id" : "b837ed7e-cb2a-43f4-84a9-8522b0c4d34d", + "name" : "api_chat", + "request" : { + "url" : "/api/chat", + "method" : "POST", + "bodyPatterns" : [ { + "equalToJson" : "{\n \"model\" : \"granite3-dense\",\n \"messages\" : [ {\n \"role\" : \"user\",\n \"content\" : \"Extract information about a customer from the text delimited by triple backticks: ```Operator: Hello, how may I help you ?\\nCustomer: Hello, I'm calling because I need to declare an accident on my main vehicle.\\nOperator: Ok, can you please give me your name ?\\nCustomer: My name is Sarah London.\\nOperator: Could you please give me your birth date ?\\nCustom [...] + "ignoreArrayOrder" : true, + "ignoreExtraElements" : true + } ] + }, + "response" : { + "status" : 200, + "body" : "{\"model\":\"granite3-dense\",\"created_at\":\"2024-10-29T14:22:27.462514101Z\",\"message\":{\"role\":\"assistant\",\"content\":\"{\\n\\\"customerSatisfied\\\": true,\\n\\\"customerName\\\": \\\"Sarah London\\\",\\n\\\"customerBirthday\\\": \\\"1986-07-10\\\",\\n\\\"summary\\\": \\\"The customer, Sarah London, called to declare an accident on her main vehicle and was informed that all expenses related to the accident would be reimbursed.\\\"\\n}\"},\"done_reason\":\"stop\", [...] + "headers" : { + "Date" : "Tue, 29 Oct 2024 14:22:27 GMT", + "Content-Type" : "application/json; charset=utf-8" + } + }, + "uuid" : "b837ed7e-cb2a-43f4-84a9-8522b0c4d34d", + "persistent" : true, + "insertionIndex" : 6 +} \ No newline at end of file