🧠 LLM Integration with AMCP
Build intelligent agents powered by Large Language Models
🔧 LLM Setup & Configuration
Configure AMCP to work with various LLM providers and local models.
OpenAI Integration
// Add OpenAI dependency
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>service</artifactId>
<version>0.18.2</version>
</dependency>
// Configuration
@Configuration
public class LLMConfig {
@Value("${openai.api.key}")
private String openaiApiKey;
@Bean
public OpenAiService openAiService() {
return new OpenAiService(openaiApiKey, Duration.ofSeconds(30));
}
@Bean
public LLMProvider llmProvider(OpenAiService openAiService) {
return new OpenAIProvider(openAiService);
}
}
Local LLM with Ollama
// Ollama configuration for local LLMs
@Configuration
public class OllamaConfig {
@Value("${ollama.base.url:http://localhost:11434}")
private String ollamaBaseUrl;
@Bean
public OllamaClient ollamaClient() {
return OllamaClient.builder()
.baseUrl(ollamaBaseUrl)
.timeout(Duration.ofMinutes(2))
.build();
}
@Bean
public LLMProvider localLLMProvider(OllamaClient client) {
return new OllamaProvider(client, "llama2"); // Use Llama 2 model
}
}
🤖 Intelligent Agent Design
Design agents that leverage LLM capabilities for decision making and content generation.
Customer Service Agent
@Agent("intelligent-customer-service")
public class IntelligentCustomerServiceAgent extends Agent {
private final LLMProvider llmProvider;
private final CustomerDataService customerService;
private final OrderService orderService;
@Override
public void onActivation() {
subscribe("customer.inquiry.*");
subscribe("customer.complaint.*");
subscribe("customer.feedback.*");
}
@EventHandler
@Subscribe("customer.inquiry.*")
public void handleCustomerInquiry(Event event) {
CustomerInquiry inquiry = event.getPayload(CustomerInquiry.class);
// Gather context
CustomerContext context = buildCustomerContext(inquiry.getCustomerId());
// Generate intelligent response
LLMRequest request = LLMRequest.builder()
.systemPrompt(buildSystemPrompt())
.userMessage(inquiry.getMessage())
.context(context)
.temperature(0.7)
.maxTokens(500)
.build();
LLMResponse response = llmProvider.generate(request);
// Determine if human escalation is needed
if (response.getConfidence() < 0.8 || containsEscalationKeywords(inquiry.getMessage())) {
escalateToHuman(inquiry, response);
} else {
sendAutomatedResponse(inquiry, response);
}
}
private CustomerContext buildCustomerContext(String customerId) {
Customer customer = customerService.getCustomer(customerId);
List<Order> recentOrders = orderService.getRecentOrders(customerId, 5);
List<Interaction> history = customerService.getInteractionHistory(customerId, 10);
return CustomerContext.builder()
.customer(customer)
.recentOrders(recentOrders)
.interactionHistory(history)
.build();
}
private String buildSystemPrompt() {
return """
You are a helpful customer service representative for an e-commerce company.
Guidelines:
- Be polite, professional, and empathetic
- Provide accurate information based on the customer context
- If you're unsure about something, say so rather than guessing
- Offer specific solutions when possible
- Keep responses concise but complete
Available actions:
- Check order status
- Process returns/refunds
- Update customer information
- Escalate to human agent if needed
""";
}
}
Content Generation Agent
@Agent("content-generator")
public class ContentGeneratorAgent extends Agent {
private final LLMProvider llmProvider;
private final ContentRepository contentRepo;
@EventHandler
@Subscribe("content.generate.request")
public void generateContent(Event event) {
ContentRequest request = event.getPayload(ContentRequest.class);
try {
GeneratedContent content = switch (request.getType()) {
case BLOG_POST -> generateBlogPost(request);
case PRODUCT_DESCRIPTION -> generateProductDescription(request);
case EMAIL_TEMPLATE -> generateEmailTemplate(request);
case SOCIAL_MEDIA -> generateSocialMediaPost(request);
default -> throw new UnsupportedOperationException("Content type not supported");
};
// Store generated content
contentRepo.save(content);
// Publish result
publish(Event.builder()
.topic("content.generated")
.payload(content)
.correlationId(event.getCorrelationId())
.build());
} catch (Exception e) {
publishError("content.generation.failed", e, event.getCorrelationId());
}
}
private GeneratedContent generateBlogPost(ContentRequest request) {
String prompt = String.format("""
Write a professional blog post about: %s
Requirements:
- Target audience: %s
- Tone: %s
- Length: %d words
- Include SEO keywords: %s
Structure:
1. Engaging introduction
2. Main content with subheadings
3. Conclusion with call-to-action
""",
request.getTopic(),
request.getTargetAudience(),
request.getTone(),
request.getWordCount(),
String.join(", ", request.getKeywords())
);
LLMResponse response = llmProvider.generate(
LLMRequest.builder()
.systemPrompt("You are a professional content writer.")
.userMessage(prompt)
.temperature(0.8)
.maxTokens(2000)
.build()
);
return GeneratedContent.builder()
.type(ContentType.BLOG_POST)
.title(extractTitle(response.getText()))
.content(response.getText())
.metadata(request.getMetadata())
.build();
}
}
✍️ Advanced Prompt Engineering
Master prompt engineering techniques for reliable and consistent LLM responses.
Few-Shot Learning
@Component
public class PromptTemplateService {
public String buildClassificationPrompt(String text, List<String> categories) {
return String.format("""
Classify the following text into one of these categories: %s
Examples:
Text: "I love this product! It works perfectly."
Category: positive
Text: "The delivery was delayed and the package was damaged."
Category: negative
Text: "The product is okay, nothing special."
Category: neutral
Text: "How do I return this item?"
Category: inquiry
Now classify this text:
Text: "%s"
Category:
""",
String.join(", ", categories),
text
);
}
public String buildExtractionPrompt(String text, List<String> fields) {
return String.format("""
Extract the following information from the text and return as JSON:
Fields to extract: %s
Example:
Text: "John Smith ordered 2 laptops for $2000, delivery to 123 Main St"
JSON: {
"customer_name": "John Smith",
"quantity": 2,
"product": "laptops",
"total_amount": 2000,
"delivery_address": "123 Main St"
}
Text: "%s"
JSON:
""",
String.join(", ", fields),
text
);
}
}
Chain of Thought Reasoning
@Service
public class ReasoningService {
public String buildReasoningPrompt(String problem) {
return String.format("""
Solve this problem step by step, showing your reasoning:
Problem: %s
Please follow this format:
1. Understanding: [Restate the problem in your own words]
2. Analysis: [Break down the problem into components]
3. Solution Steps: [List the steps to solve it]
4. Final Answer: [Provide the final answer]
5. Confidence: [Rate your confidence 1-10 and explain why]
Let's work through this systematically:
""", problem);
}
public String buildDecisionPrompt(String scenario, List<String> options) {
return String.format("""
Make a decision for the following scenario by evaluating each option:
Scenario: %s
Options: %s
Please analyze each option considering:
1. Pros and cons
2. Risk assessment
3. Expected outcomes
4. Resource requirements
Then provide:
- Recommended option with justification
- Alternative approaches if the primary fails
- Key success metrics to monitor
""",
scenario,
String.join(", ", options)
);
}
}
🧠 Context Management & Memory
Implement sophisticated context management for conversational agents.
Conversation Context Manager
@Component
public class ConversationContextManager {
private final RedisTemplate<String, ConversationContext> redisTemplate;
private final VectorDatabase vectorDB;
public ConversationContext getContext(String conversationId) {
ConversationContext context = redisTemplate.opsForValue()
.get("conversation:" + conversationId);
if (context == null) {
context = new ConversationContext(conversationId);
}
return context;
}
public void updateContext(String conversationId, String userMessage, String assistantResponse) {
ConversationContext context = getContext(conversationId);
// Add to conversation history
context.addExchange(userMessage, assistantResponse);
// Extract and store key information
KeyInformation keyInfo = extractKeyInformation(userMessage, assistantResponse);
context.addKeyInformation(keyInfo);
// Store in vector database for semantic search
storeInVectorDB(conversationId, userMessage, assistantResponse);
// Update Redis cache
redisTemplate.opsForValue().set(
"conversation:" + conversationId,
context,
Duration.ofHours(24)
);
}
public String buildContextualPrompt(String conversationId, String newMessage) {
ConversationContext context = getContext(conversationId);
// Get relevant past conversations
List<String> relevantHistory = vectorDB.semanticSearch(
newMessage,
"conversation:" + conversationId,
5
);
StringBuilder prompt = new StringBuilder();
prompt.append("Previous conversation context:\n");
// Add key information
context.getKeyInformation().forEach(info ->
prompt.append("- ").append(info.getSummary()).append("\n")
);
// Add relevant history
prompt.append("\nRelevant past exchanges:\n");
relevantHistory.forEach(exchange ->
prompt.append(exchange).append("\n")
);
// Add recent conversation
prompt.append("\nRecent conversation:\n");
context.getRecentExchanges(3).forEach(exchange ->
prompt.append("User: ").append(exchange.getUserMessage()).append("\n")
.append("Assistant: ").append(exchange.getAssistantResponse()).append("\n")
);
prompt.append("\nNew message: ").append(newMessage);
return prompt.toString();
}
}
🌟 Real-world Examples
Complete examples of LLM-powered AMCP agents in production scenarios.
Intelligent Document Processor
@Agent("document-processor")
public class IntelligentDocumentProcessor extends Agent {
private final LLMProvider llmProvider;
private final DocumentStorage documentStorage;
private final WorkflowOrchestrator orchestrator;
@EventHandler
@Subscribe("document.uploaded")
public void processDocument(Event event) {
DocumentUpload upload = event.getPayload(DocumentUpload.class);
// Extract text from document
String documentText = extractText(upload.getDocumentPath());
// Classify document type
DocumentType type = classifyDocument(documentText);
// Extract structured data based on type
StructuredData data = extractStructuredData(documentText, type);
// Validate extracted data
ValidationResult validation = validateData(data, type);
if (validation.isValid()) {
// Process document based on type
processDocumentByType(upload, type, data);
} else {
// Send for human review
sendForHumanReview(upload, validation.getIssues());
}
}
private DocumentType classifyDocument(String text) {
String prompt = """
Classify this document into one of these types:
- invoice
- contract
- receipt
- legal_document
- technical_specification
- other
Document text: %s
Classification:
""".formatted(text.substring(0, Math.min(text.length(), 2000)));
LLMResponse response = llmProvider.generate(
LLMRequest.builder()
.systemPrompt("You are a document classification expert.")
.userMessage(prompt)
.temperature(0.1)
.build()
);
return DocumentType.fromString(response.getText().trim());
}
private StructuredData extractStructuredData(String text, DocumentType type) {
String extractionPrompt = buildExtractionPrompt(type);
LLMResponse response = llmProvider.generate(
LLMRequest.builder()
.systemPrompt("Extract structured data from documents accurately.")
.userMessage(extractionPrompt + "\n\nDocument:\n" + text)
.temperature(0.0)
.build()
);
return parseStructuredData(response.getText(), type);
}
}
Code Review Assistant
@Agent("code-review-assistant")
public class CodeReviewAssistant extends Agent {
@EventHandler
@Subscribe("code.review.request")
public void reviewCode(Event event) {
CodeReviewRequest request = event.getPayload(CodeReviewRequest.class);
// Analyze code for different aspects
List<ReviewComment> comments = new ArrayList<>();
// Security analysis
comments.addAll(analyzeSecurityIssues(request.getCode()));
// Performance analysis
comments.addAll(analyzePerformance(request.getCode()));
// Code quality analysis
comments.addAll(analyzeCodeQuality(request.getCode()));
// Best practices check
comments.addAll(checkBestPractices(request.getCode(), request.getLanguage()));
// Generate summary
String summary = generateReviewSummary(comments, request.getCode());
CodeReviewResult result = CodeReviewResult.builder()
.comments(comments)
.summary(summary)
.overallScore(calculateOverallScore(comments))
.recommendations(generateRecommendations(comments))
.build();
publish(Event.builder()
.topic("code.review.completed")
.payload(result)
.correlationId(event.getCorrelationId())
.build());
}
private List<ReviewComment> analyzeSecurityIssues(String code) {
String prompt = """
Analyze this code for security vulnerabilities:
Look for:
- SQL injection vulnerabilities
- XSS vulnerabilities
- Authentication/authorization issues
- Input validation problems
- Sensitive data exposure
For each issue found, provide:
- Line number (if applicable)
- Severity (high/medium/low)
- Description of the issue
- Suggested fix
Code:
%s
""".formatted(code);
LLMResponse response = llmProvider.generate(
LLMRequest.builder()
.systemPrompt("You are a security expert reviewing code for vulnerabilities.")
.userMessage(prompt)
.temperature(0.2)
.build()
);
return parseSecurityComments(response.getText());
}
}