/ driftkit-workflows / LLMAGENT.md
LLMAGENT.md
1 # LLMAgent Documentation 2 3 ## Overview 4 5 LLMAgent is a simplified, type-safe SDK for AI interactions in the DriftKit framework. It provides a high-level interface over the ModelClient API with built-in features for tool calling, structured output, memory management, and more. 6 7 ## Key Features 8 9 - **Unified Interface**: Simple `execute*()` methods for all operations 10 - **Type Safety**: `AgentResponse<T>` wrapper for typed results 11 - **Tool Calling**: Both manual and automatic execution modes 12 - **Structured Output**: JSON schema-based extraction with type safety 13 - **Multi-modal Support**: Text + images in single interface 14 - **Memory Management**: Conversation history with `ChatMemory` 15 - **Prompt Templates**: Integration with `PromptService` 16 - **Builder Pattern**: Easy configuration and setup 17 - **Request Tracing**: Built-in monitoring and debugging 18 19 ## Basic Usage 20 21 ### Creating an LLMAgent 22 23 ```java 24 LLMAgent agent = LLMAgent.builder() 25 .modelClient(modelClient) 26 .systemMessage("You are a helpful assistant") 27 .temperature(0.7) 28 .maxTokens(1000) 29 .chatMemory(chatMemory) 30 .build(); 31 ``` 32 33 ### Simple Text Chat 34 35 ```java 36 AgentResponse<String> response = agent.executeText("What is the capital of France?"); 37 String answer = response.getText(); 38 ``` 39 40 ### Multi-modal Chat (Text + Images) 41 42 ```java 43 byte[] imageData = Files.readAllBytes(Paths.get("image.jpg")); 44 AgentResponse<String> response = agent.executeWithImages("What's in this image?", imageData); 45 ``` 46 47 ### Tool Calling 48 49 #### Manual Tool Execution 50 51 ```java 52 // Get tool calls for manual execution 53 AgentResponse<List<ToolCall>> response = agent.executeForToolCalls("Get weather in Paris"); 54 55 for (ToolCall toolCall : response.getToolCalls()) { 56 ToolExecutionResult result = agent.executeToolCall(toolCall); 57 WeatherInfo weather = result.getTypedResult(); // Type-safe result 58 System.out.println("Temperature: " + weather.getTemperature()); 59 } 60 ``` 61 62 #### Automatic Tool Execution 63 64 ```java 65 // Register tools 66 agent.registerTool("getCurrentWeather", weatherService, "Get current weather") 67 .registerTool("searchDatabase", dbService, "Search database"); 68 69 // Execute with automatic tool calling 70 AgentResponse<List<ToolExecutionResult>> response = agent.executeWithTools( 71 "What's the weather in cities where our customers are located?" 72 ); 73 74 // Access typed results 75 for (ToolExecutionResult result : response.getToolResults()) { 76 if (result.isSuccess()) { 77 Object typedResult = result.getTypedResult(); 78 } 79 } 80 ``` 81 82 ### Structured Output Extraction 83 84 ```java 85 // Define your data model 86 public record Person(String name, Integer age, String occupation) {} 87 88 // Extract structured data 89 AgentResponse<Person> response = agent.executeStructured( 90 "John is 30 years old and works as a software engineer", 91 Person.class 92 ); 93 94 Person person = response.getStructuredData(); 95 ``` 96 97 ### Using Prompt Templates 98 99 ```java 100 // Use predefined prompt template 101 Map<String, Object> variables = Map.of( 102 "topic", "AI Ethics", 103 "length", "500 words" 104 ); 105 106 AgentResponse<String> response = agent.executeWithPrompt("blog-post-template", variables); 107 ``` 108 109 ## Advanced Patterns 110 111 ### Loop Pattern - Iterative Refinement 112 113 The LoopAgent pattern enables iterative refinement where a worker agent generates content and an evaluator agent determines if it meets criteria. 114 115 ```java 116 // Worker agent - generates content 117 Agent writer = LLMAgent.builder() 118 .modelClient(modelClient) 119 .systemMessage("Write engaging blog posts about technology") 120 .build(); 121 122 // Evaluator agent - checks quality 123 Agent editor = LLMAgent.builder() 124 .modelClient(modelClient) 125 .systemMessage("Evaluate blog posts. Return JSON: " + 126 "{\"status\": \"COMPLETE\"} if excellent, " + 127 "{\"status\": \"REVISE\", \"feedback\": \"specific improvements\"}") 128 .build(); 129 130 // Create loop agent 131 LoopAgent blogWriter = LoopAgent.builder() 132 .worker(writer) 133 .evaluator(editor) 134 .stopCondition(LoopStatus.COMPLETE) 135 .maxIterations(5) 136 .build(); 137 138 String finalPost = blogWriter.execute("Write about quantum computing"); 139 ``` 140 141 #### Loop Status Options 142 143 - `COMPLETE` - Task completed successfully 144 - `REVISE` - Output needs revision based on feedback 145 - `RETRY` - Retry with same input 146 - `FAILED` - Task failed 147 - `CONTINUE` - Continue to next iteration 148 149 ### Sequential Pattern - Multi-Stage Processing 150 151 The SequentialAgent chains multiple agents where each output becomes the next input. 152 153 ```java 154 // Create a multi-stage pipeline 155 SequentialAgent pipeline = SequentialAgent.builder() 156 .agent(LLMAgent.builder() 157 .modelClient(modelClient) 158 .systemMessage("Extract key facts from the text") 159 .build()) 160 .agent(LLMAgent.builder() 161 .modelClient(modelClient) 162 .systemMessage("Organize facts into categories") 163 .build()) 164 .agent(LLMAgent.builder() 165 .modelClient(modelClient) 166 .systemMessage("Create a summary report") 167 .build()) 168 .build(); 169 170 String report = pipeline.execute(longDocument); 171 ``` 172 173 ### Combined Patterns 174 175 Combine Loop and Sequential for complex workflows: 176 177 ```java 178 // Sequential processing pipeline 179 SequentialAgent processor = SequentialAgent.builder() 180 .agent(dataExtractor) 181 .agent(dataTransformer) 182 .agent(reportGenerator) 183 .build(); 184 185 // Add quality control loop 186 LoopAgent qualityControlled = LoopAgent.builder() 187 .worker(processor) 188 .evaluator(qualityChecker) 189 .stopCondition(LoopStatus.COMPLETE) 190 .build(); 191 ``` 192 193 ### Agent as Tool 194 195 Agents can be used as tools by other agents: 196 197 ```java 198 // Specialized agents 199 Agent researcher = LLMAgent.builder() 200 .modelClient(modelClient) 201 .systemMessage("Research topics thoroughly") 202 .name("Researcher") 203 .build(); 204 205 Agent factChecker = LLMAgent.builder() 206 .modelClient(modelClient) 207 .systemMessage("Verify facts and claims") 208 .name("FactChecker") 209 .build(); 210 211 // Convert to tools 212 ToolInfo researchTool = AgentAsTool.create("research", "Research topics", researcher); 213 ToolInfo factCheckTool = AgentAsTool.create("factCheck", "Verify facts", factChecker); 214 215 // Master agent with sub-agents as tools 216 Agent masterAgent = LLMAgent.builder() 217 .modelClient(modelClient) 218 .systemMessage("Write accurate, well-researched articles") 219 .addTool(researchTool) 220 .addTool(factCheckTool) 221 .build(); 222 ``` 223 224 ## Real-World Use Cases 225 226 ### 1. Customer Support System 227 228 ```java 229 // Intent classifier 230 Agent classifier = LLMAgent.builder() 231 .modelClient(modelClient) 232 .systemMessage("Classify customer inquiries: billing, technical, general") 233 .build(); 234 235 // Response generators for each category 236 Agent billingAgent = LLMAgent.builder() 237 .modelClient(modelClient) 238 .systemMessage("Handle billing inquiries professionally") 239 .build(); 240 241 Agent technicalAgent = LLMAgent.builder() 242 .modelClient(modelClient) 243 .systemMessage("Provide technical support") 244 .build(); 245 246 // Router agent with specialized agents as tools 247 Agent supportRouter = LLMAgent.builder() 248 .modelClient(modelClient) 249 .systemMessage("Route and handle customer inquiries") 250 .addTool(AgentAsTool.create("billing", "Handle billing", billingAgent)) 251 .addTool(AgentAsTool.create("technical", "Handle technical", technicalAgent)) 252 .build(); 253 ``` 254 255 ### 2. Document Processing Pipeline 256 257 ```java 258 // OCR and extraction 259 Agent ocrAgent = LLMAgent.builder() 260 .modelClient(modelClient) 261 .systemMessage("Extract text from document images") 262 .build(); 263 264 // Data structuring 265 Agent structuringAgent = LLMAgent.builder() 266 .modelClient(modelClient) 267 .systemMessage("Convert extracted text to structured data") 268 .build(); 269 270 // Validation 271 Agent validator = LLMAgent.builder() 272 .modelClient(modelClient) 273 .systemMessage("Validate data completeness and accuracy") 274 .build(); 275 276 // Complete pipeline with validation loop 277 SequentialAgent extraction = SequentialAgent.builder() 278 .agent(ocrAgent) 279 .agent(structuringAgent) 280 .build(); 281 282 LoopAgent validatedPipeline = LoopAgent.builder() 283 .worker(extraction) 284 .evaluator(validator) 285 .stopCondition(LoopStatus.COMPLETE) 286 .build(); 287 ``` 288 289 ### 3. Code Generation and Review 290 291 ```java 292 // Code generator 293 Agent codeGenerator = LLMAgent.builder() 294 .modelClient(modelClient) 295 .systemMessage("Generate clean, efficient code following best practices") 296 .build(); 297 298 // Code reviewer 299 Agent codeReviewer = LLMAgent.builder() 300 .modelClient(modelClient) 301 .systemMessage("Review code for bugs, security issues, and improvements. " + 302 "Return {\"status\": \"COMPLETE\"} if good, " + 303 "{\"status\": \"REVISE\", \"feedback\": \"issues found\"}") 304 .build(); 305 306 // Iterative code improvement 307 LoopAgent codeWriter = LoopAgent.builder() 308 .worker(codeGenerator) 309 .evaluator(codeReviewer) 310 .stopCondition(LoopStatus.COMPLETE) 311 .maxIterations(3) 312 .build(); 313 314 String code = codeWriter.execute("Create a REST API endpoint for user management"); 315 ``` 316 317 ### 4. Multi-Language Content Creation 318 319 ```java 320 // Content creation pipeline 321 SequentialAgent contentPipeline = SequentialAgent.builder() 322 .agent(LLMAgent.builder() 323 .modelClient(modelClient) 324 .systemMessage("Write content in English") 325 .build()) 326 .agent(LLMAgent.builder() 327 .modelClient(modelClient) 328 .systemMessage("Translate to Spanish preserving tone") 329 .build()) 330 .agent(LLMAgent.builder() 331 .modelClient(modelClient) 332 .systemMessage("Adapt for Latin American audience") 333 .build()) 334 .build(); 335 336 // Quality control 337 Agent qualityChecker = LLMAgent.builder() 338 .modelClient(modelClient) 339 .systemMessage("Check translation quality and cultural appropriateness") 340 .build(); 341 342 LoopAgent multilingualContent = LoopAgent.builder() 343 .worker(contentPipeline) 344 .evaluator(qualityChecker) 345 .stopCondition(LoopStatus.COMPLETE) 346 .build(); 347 ``` 348 349 ### 5. Data Analysis Workflow 350 351 ```java 352 // Analysis pipeline 353 SequentialAgent analysisWorkflow = SequentialAgent.builder() 354 .agent(LLMAgent.builder() 355 .modelClient(modelClient) 356 .systemMessage("Clean and preprocess data") 357 .build()) 358 .agent(LLMAgent.builder() 359 .modelClient(modelClient) 360 .systemMessage("Perform statistical analysis") 361 .build()) 362 .agent(LLMAgent.builder() 363 .modelClient(modelClient) 364 .systemMessage("Generate insights and recommendations") 365 .build()) 366 .agent(LLMAgent.builder() 367 .modelClient(modelClient) 368 .systemMessage("Create executive summary") 369 .build()) 370 .build(); 371 372 String analysis = analysisWorkflow.execute(rawData); 373 ``` 374 375 ## Best Practices 376 377 1. **Clear System Messages**: Provide specific, clear instructions in system messages 378 2. **Type Safety**: Use structured output for type-safe data extraction 379 3. **Error Handling**: Always handle potential failures in tool execution 380 4. **Memory Management**: Configure appropriate token limits for conversations 381 5. **Tool Design**: Create focused, single-purpose tools 382 6. **Evaluation Criteria**: Define clear, objective criteria for loop evaluators 383 7. **Iteration Limits**: Set reasonable max iterations to prevent infinite loops 384 8. **Prompt Engineering**: Use prompt templates for consistent formatting 385 386 ## Integration with Spring Boot 387 388 ```java 389 @Service 390 public class AIService { 391 private final LLMAgent agent; 392 393 public AIService(ModelClient modelClient, ChatMemory chatMemory) { 394 this.agent = LLMAgent.builder() 395 .modelClient(modelClient) 396 .systemMessage("Professional AI assistant") 397 .chatMemory(chatMemory) 398 .temperature(0.7) 399 .build(); 400 } 401 402 @PostMapping("/chat") 403 public String chat(@RequestBody String message) { 404 return agent.executeText(message).getText(); 405 } 406 407 @PostMapping("/analyze") 408 public AnalysisResult analyze(@RequestBody String data) { 409 return agent.executeStructured(data, AnalysisResult.class) 410 .getStructuredData(); 411 } 412 } 413 ``` 414 415 ## Performance Considerations 416 417 1. **Caching**: LLMAgent supports response caching for repeated queries 418 2. **Parallel Execution**: Use multiple agents in parallel when possible 419 3. **Token Optimization**: Monitor token usage with memory management 420 4. **Tool Efficiency**: Design tools to minimize LLM calls 421 5. **Batch Processing**: Process multiple items in single requests when possible 422 423 ## Debugging and Monitoring 424 425 Enable request tracing for debugging: 426 427 ```java 428 LLMAgent agent = LLMAgent.builder() 429 .modelClient(modelClient) 430 .requestTracingProvider(tracingProvider) 431 .build(); 432 ``` 433 434 Access trace information: 435 - Request/response details 436 - Token usage 437 - Execution time 438 - Tool call history 439 - Error details 440 441 ## Migration from Direct ModelClient 442 443 Before (ModelClient): 444 ```java 445 ModelTextRequest request = ModelTextRequest.builder() 446 .messages(List.of(createMessage(text))) 447 .temperature(0.7) 448 .build(); 449 ModelTextResponse response = modelClient.textToText(request); 450 String result = response.getChoices().get(0).getMessage().getContent(); 451 ``` 452 453 After (LLMAgent): 454 ```java 455 String result = agent.executeText(text).getText(); 456 ``` 457 458 The LLMAgent provides a cleaner, more maintainable API while preserving all the power of the underlying ModelClient.