CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-ai--spring-ai-client-chat

Spring AI Chat Client provides a fluent API for building AI-powered applications with LLMs, supporting advisors, streaming, structured outputs, and conversation memory

Overview
Eval results
Files

working-with-advisors.mddocs/guides/

Working with Advisors

Advisors are interceptors that modify requests and responses in a chain-of-responsibility pattern.

Using Built-in Advisors

Logging

import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;

ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(SimpleLoggerAdvisor.builder().build())
    .build();

Content Filtering

import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;

SafeGuardAdvisor safeguard = SafeGuardAdvisor.builder()
    .sensitiveWords(List.of("password", "secret"))
    .failureResponse("Request blocked for security.")
    .build();

ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(safeguard)
    .build();

Conversation Memory

import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;

ChatMemory chatMemory = new InMemoryChatMemory();

MessageChatMemoryAdvisor memoryAdvisor = 
    MessageChatMemoryAdvisor.builder(chatMemory)
        .conversationId("user-123")
        .build();

ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(memoryAdvisor)
    .build();

Structured Output Validation

import org.springframework.ai.chat.client.advisor.StructuredOutputValidationAdvisor;

StructuredOutputValidationAdvisor validator =
    StructuredOutputValidationAdvisor.builder()
        .outputType(Person.class)
        .maxRepeatAttempts(3)
        .build();

ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(validator)
    .build();

Advisor Ordering

Advisors execute in order (lower values first):

ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(
        SafeGuardAdvisor.builder().order(100).build(),           // First
        MessageChatMemoryAdvisor.builder(chatMemory)
            .order(1001).build(),                                 // Second
        SimpleLoggerAdvisor.builder()
            .order(Ordered.LOWEST_PRECEDENCE).build()            // Last
    )
    .build();

Standard Order Values:

  • 100-500: Security/validation
  • 1001: Memory (DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER)
  • 3000: Tool calling
  • 5000: Output validation
  • LOWEST_PRECEDENCE: Logging

Creating Custom Advisors

Simple Advisor (Call Only)

import org.springframework.ai.chat.client.advisor.api.CallAdvisor;

class TimingAdvisor implements CallAdvisor {
    @Override
    public ChatClientResponse adviseCall(
        ChatClientRequest request,
        CallAdvisorChain chain
    ) {
        long start = System.currentTimeMillis();
        ChatClientResponse response = chain.nextCall(request);
        long duration = System.currentTimeMillis() - start;
        System.out.println("Request took: " + duration + "ms");
        return response;
    }
    
    @Override
    public String getName() {
        return "TimingAdvisor";
    }
    
    @Override
    public int getOrder() {
        return 0;
    }
}

BaseAdvisor (Call + Stream)

import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;

class MetadataAdvisor implements BaseAdvisor {
    @Override
    public ChatClientRequest before(
        ChatClientRequest request,
        AdvisorChain chain
    ) {
        request.context().put("requestId", UUID.randomUUID().toString());
        request.context().put("timestamp", System.currentTimeMillis());
        return request;
    }
    
    @Override
    public ChatClientResponse after(
        ChatClientResponse response,
        AdvisorChain chain
    ) {
        long duration = System.currentTimeMillis() - 
            (long) response.context().get("timestamp");
        response.context().put("duration", duration);
        return response;
    }
    
    @Override
    public String getName() {
        return "MetadataAdvisor";
    }
    
    @Override
    public int getOrder() {
        return 100;
    }
}

Per-Request Advisors

Override default advisors for specific requests:

// Default advisors
ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(advisor1, advisor2)
    .build();

// Override for this request
String response = client
    .prompt("Query")
    .advisors(advisor3, advisor4)  // Replaces defaults
    .call()
    .content();

Advisor Parameters

Pass parameters to advisors at request time:

chatClient
    .prompt("Continue conversation")
    .advisors(spec -> spec
        .advisors(memoryAdvisor)
        .param("conversationId", "user-123")
        .param("maxHistory", 10)
    )
    .call()
    .content();

Context Sharing

Advisors share data through context maps:

class FirstAdvisor implements BaseAdvisor {
    @Override
    public ChatClientRequest before(ChatClientRequest request, AdvisorChain chain) {
        request.context().put("myData", "value");
        return request;
    }
    // ...
}

class SecondAdvisor implements BaseAdvisor {
    @Override
    public ChatClientRequest before(ChatClientRequest request, AdvisorChain chain) {
        String data = (String) request.context().get("myData");
        // Use data
        return request;
    }
    // ...
}

Next Steps

  • Conversation Memory - Memory advisor patterns
  • Tool Calling - Tool call advisor
  • Custom Advisors Reference - Complete guide
  • Utility Advisors Reference - Built-in advisors

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework-ai--spring-ai-client-chat

docs

index.md

tile.json