Skip to content

Commit

Permalink
upgrade to SB 3.4 and polish observability (#130)
Browse files Browse the repository at this point in the history
* upgrade to SB 3.4 and polish observability

* upgrade docker

* fix : tests

* polish
  • Loading branch information
rajadilipkolli authored Dec 24, 2024
1 parent b037b5c commit 8815e97
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 103 deletions.
79 changes: 61 additions & 18 deletions rag/rag-springai-ollama-llm/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,62 @@
services:
ollama:
image: langchain4j/ollama-llama3:latest
ports:
- '11434:11434'
redis-stack:
image: redis/redis-stack-server
ports:
- '6379:6379'
lgtm-stack:
image: grafana/otel-lgtm:0.8.0
extra_hosts: ['host.docker.internal:host-gateway']
container_name: lgtm-stack
environment:
- OTEL_METRIC_EXPORT_INTERVAL=500
ports:
- "3000:3000"
- "4317:4317"
- "4318:4318"

ollama:
container_name: ollama
image: ollama/ollama:latest
ports:
- '11434:11434'

postgresqldb:
container_name: postgresqldb
image: pgvector/pgvector:pg17
extra_hosts: [ 'host.docker.internal:host-gateway' ]
restart: always
environment:
- POSTGRES_USER=appuser
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=appdb
- PGPASSWORD=secret
logging:
options:
max-size: 10m
max-file: "3"
ports:
- '5432:5432'
healthcheck:
test: "pg_isready -U appuser -d appdb"
interval: 2s
timeout: 20s
retries: 10

pgadmin:
container_name: pgadmin_container
image: dpage/pgadmin4
extra_hosts: [ 'host.docker.internal:host-gateway' ]
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:[email protected]}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
PGADMIN_CONFIG_SERVER_MODE: "False"
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False"
ports:
- "${PGADMIN_PORT:-5050}:80"
depends_on:
postgresqldb:
condition: service_healthy
volumes:
- ./docker_pgadmin_servers.json:/pgadmin4/servers.json
entrypoint:
- "/bin/sh"
- "-c"
- "/bin/echo 'postgresqldb:5432:*:appuser:secret' > /tmp/pgpassfile && chmod 600 /tmp/pgpassfile && /entrypoint.sh"

lgtm-stack:
image: grafana/otel-lgtm:0.8.1
extra_hosts: [ 'host.docker.internal:host-gateway' ]
container_name: lgtm-stack
environment:
- OTEL_METRIC_EXPORT_INTERVAL=500
ports:
- "3000:3000"
- "4317:4317"
- "4318:4318"
- "9090:9090"
14 changes: 14 additions & 0 deletions rag/rag-springai-ollama-llm/docker/docker_pgadmin_servers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"Servers": {
"1": {
"Name": "Docker Compose DB",
"Group": "Servers",
"Port": 5432,
"Username": "appuser",
"Host": "postgresqldb",
"SSLMode": "prefer",
"MaintenanceDB": "appdb",
"PassFile": "/tmp/pgpassfile"
}
}
}
48 changes: 34 additions & 14 deletions rag/rag-springai-ollama-llm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.6</version>
<version>3.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.learning.ai</groupId>
Expand All @@ -16,7 +16,8 @@

<properties>
<java.version>21</java.version>
<spring-ai.version>1.0.0-M4</spring-ai.version>
<spring-ai.version>1.0.0-M5</spring-ai.version>
<otelInstrumentation.version>2.10.0-alpha</otelInstrumentation.version>
<spotless.version>2.43.0</spotless.version>
</properties>

Expand All @@ -39,11 +40,7 @@
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-redis-store-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
Expand All @@ -56,7 +53,14 @@
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version>
<version>2.7.0</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

<dependency>
Expand All @@ -76,6 +80,17 @@
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-otlp</artifactId>
</dependency>
<dependency>
<groupId>net.ttddyy.observation</groupId>
<artifactId>datasource-micrometer-spring-boot</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-logback-appender-1.0</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand All @@ -97,16 +112,14 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.redis.testcontainers</groupId>
<artifactId>testcontainers-redis</artifactId>
<groupId>org.testcontainers</groupId>
<artifactId>grafana</artifactId>
<scope>test</scope>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>grafana</artifactId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
<version>1.20.4</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
Expand All @@ -124,6 +137,13 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-bom-alpha</artifactId>
<version>${otelInstrumentation.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand All @@ -144,7 +164,7 @@
<configuration>
<java>
<palantirJavaFormat>
<version>2.47.0</version>
<version>2.50.0</version>
</palantirJavaFormat>
<importOrder/>
<removeUnusedImports/>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.chat.client.advisor.RetrievalAugmentationAdvisor;
import org.springframework.ai.rag.generation.augmentation.ContextualQueryAugmenter;
import org.springframework.ai.rag.retrieval.search.VectorStoreDocumentRetriever;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

Expand All @@ -15,33 +14,29 @@ public class AIChatService {

private static final Logger LOGGER = LoggerFactory.getLogger(AIChatService.class);

private static final String template =
"""
You are a helpful assistant, conversing with a user about the subjects contained in a set of documents.
Use the information from the DOCUMENTS section to provide accurate answers. If unsure or if the answer
isn't found in the DOCUMENTS section, simply state that you don't know the answer.
private final ChatClient aiClient;

DOCUMENTS:
{question_answer_context}
public AIChatService(ChatClient.Builder builder, VectorStore vectorStore) {

""";
var documentRetriever = VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.similarityThreshold(0.50)
.build();

private final ChatClient aiClient;
private final VectorStore vectorStore;
var queryAugmenter =
ContextualQueryAugmenter.builder().allowEmptyContext(true).build();

public AIChatService(ChatClient.Builder builder, VectorStore vectorStore) {
this.aiClient = builder.build();
this.vectorStore = vectorStore;
RetrievalAugmentationAdvisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
.documentRetriever(documentRetriever)
.queryAugmenter(queryAugmenter)
.build();
this.aiClient =
builder.clone().defaultAdvisors(retrievalAugmentationAdvisor).build();
}

public String chat(String query) {
ChatResponse aiResponse = aiClient.prompt()
.advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.query(query), template))
.user(query)
.call()
.chatResponse();
String aiResponse = aiClient.prompt().user(query).call().content();
LOGGER.info("Response received from call :{}", aiResponse);
Generation generation = aiResponse.getResult();
return (generation != null) ? generation.getOutput().getContent() : "";
return aiResponse;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.learning.ai.llmragwithspringai.service;

import java.util.Map;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.DocumentReader;
Expand Down Expand Up @@ -58,11 +59,11 @@ public void loadData(Resource documentResource) {
return documents;
};
vectorStore.accept(metadataEnricher.apply(tokenTextSplitter.apply(documentReader.get())));
LOGGER.info("Loaded document to redis vector database.");
LOGGER.info("Loaded document to vector database.");
}
}

public long count() {
return this.vectorStore.similaritySearch("*").size();
return Objects.requireNonNull(this.vectorStore.similaritySearch("*")).size();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## WARNING: Development-only configuration
## The following setting will DELETE existing vector store data on startup
spring.ai.vectorstore.pgvector.removeExistingVectorStoreTable=true
spring.ai.ollama.baseUrl=http://localhost:11434


logging.level.org.springframework.ai.rag=debug

spring.datasource.url=jdbc:postgresql://localhost/appdb
spring.datasource.username=appuser
spring.datasource.password=secret
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,32 @@ spring.application.name=rag-springai-ollama-llm
spring.threads.virtual.enabled=true
spring.mvc.problemdetails.enabled=true

spring.ai.ollama.init.pull-model-strategy=WHEN_MISSING
spring.ai.ollama.chat.options.model=mistral
spring.ai.ollama.chat.options.temperature=0.3
spring.ai.ollama.chat.options.top-k=2
spring.ai.ollama.chat.options.top-p=0.2

spring.ai.ollama.embedding.options.model=nomic-embed-text

spring.ai.vectorstore.redis.index=vector_store
spring.ai.vectorstore.redis.prefix=ai
spring.ai.vectorstore.redis.initialize-schema=true
#PgVector
spring.ai.vectorstore.observations.include-query-response=true
spring.ai.vectorstore.pgvector.initialize-schema=true

spring.ai.ollama.baseUrl=http://localhost:11434
spring.http.client.connect-timeout=PT1M
spring.http.client.read-timeout=PT5M

spring.testcontainers.beans.startup=parallel

##Observability
spring.ai.chat.observations.include-completion=true
spring.ai.chat.observations.include-prompt=true
spring.ai.chat.client.observations.include-input=true

management.endpoints.web.exposure.include=*
management.metrics.tags.service.name=${spring.application.name}
management.tracing.sampling.probability=1.0
management.otlp.tracing.endpoint=http://localhost:4318/v1/traces
management.otlp.logging.endpoint=http://localhost:4318/v1/logs

logging.level.org.springframework.ai.rag=info
16 changes: 16 additions & 0 deletions rag/rag-springai-ollama-llm/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />

<appender name="OpenTelemetry"
class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender">
<captureExperimentalAttributes>true</captureExperimentalAttributes>
<captureCodeAttributes>true</captureCodeAttributes>
<captureKeyValuePairAttributes>true</captureKeyValuePairAttributes>
</appender>

<root level="INFO">
<appender-ref ref="OpenTelemetry"/>
</root>

</configuration>
Loading

0 comments on commit 8815e97

Please sign in to comment.