/ 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.