Skip to content

Commit 99a5da9

Browse files
authored
Add Tool Argument Augmenter demo with chat memory integration (#89)
* Add Tool Argument Augmenter demo with chat memory integration Introduce a companion example for the "Explainable AI Agents" blog post, demonstrating the tool-augmenter library for capturing LLM reasoning during tool calls. Key features demonstrated: - AgentThinking record to capture inner thoughts, confidence levels, and memory notes from the LLM during tool execution - AugmentedToolCallbackProvider for transparent schema augmentation - Integration with ToolCallAdvisor and MessageChatMemoryAdvisor to persist reasoning insights in conversation history - Custom logging advisor for request/response observability This pattern enables debugging, observability, and memory-enhanced reasoning for AI agents without modifying underlying tool implementations. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
1 parent 464630d commit 99a5da9

10 files changed

Lines changed: 902 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/mvnw text eol=lf
2+
*.cmd text eol=crlf
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
HELP.md
2+
target/
3+
.mvn/wrapper/maven-wrapper.jar
4+
!**/src/main/**/target/
5+
!**/src/test/**/target/
6+
7+
### STS ###
8+
.apt_generated
9+
.classpath
10+
.factorypath
11+
.project
12+
.settings
13+
.springBeans
14+
.sts4-cache
15+
16+
### IntelliJ IDEA ###
17+
.idea
18+
*.iws
19+
*.iml
20+
*.ipr
21+
22+
### NetBeans ###
23+
/nbproject/private/
24+
/nbbuild/
25+
/dist/
26+
/nbdist/
27+
/.nb-gradle/
28+
build/
29+
!**/src/main/**/build/
30+
!**/src/test/**/build/
31+
32+
### VS Code ###
33+
.vscode/
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
wrapperVersion=3.3.4
2+
distributionType=only-script
3+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# Recursive Advisor with Memory and Tool Argument Augmentation
2+
3+
This example demonstrates how to build **explainable AI agents** using Spring AI by capturing LLM reasoning during tool calls and integrating with chat memory for enhanced context across conversations.
4+
5+
## Overview
6+
7+
When building AI agents with tool calling capabilities, understanding **why** an LLM chose a particular tool is crucial for debugging, observability, and building trustworthy AI systems. This demo showcases the Spring AI [Tool Argument Augmenter](https://docs.spring.io/spring-ai/reference/2.0-SNAPSHOT/api/tools.html#tool-argument-augmentation) utilities which enables:
8+
9+
- **Capturing LLM Reasoning**: Extract inner thoughts, confidence levels, and memory notes during tool execution
10+
- **Transparent Schema Augmentation**: Dynamically extend tool schemas without modifying underlying tool implementations
11+
- **Memory-Enhanced Reasoning**: Persist reasoning insights in conversation history for improved decision-making across extended interactions
12+
13+
## How It Works
14+
15+
```
16+
┌─────────────────────────────────────────────────────────────────────────┐
17+
│ Tool Argument Augmenter Flow │
18+
├─────────────────────────────────────────────────────────────────────────┤
19+
│ │
20+
│ 1. User asks: "What is current weather in Paris?" │
21+
│ │ │
22+
│ ▼ │
23+
│ 2. Tool Definition Augmentation │
24+
│ Original: { location: string } │
25+
│ Augmented: { location: string, innerThought: string, │
26+
│ confidence: string, memoryNotes: string[] } │
27+
│ │ │
28+
│ ▼ │
29+
│ 3. LLM Response with Reasoning │
30+
│ { │
31+
│ "location": "Paris", │
32+
│ "innerThought": "User wants weather info for Paris...", │
33+
│ "confidence": "high", │
34+
│ "memoryNotes": ["User interested in Paris weather"] │
35+
│ } │
36+
│ │ │
37+
│ ▼ │
38+
│ 4. Argument Consumer processes reasoning (logging, memory storage) │
39+
│ │ │
40+
│ ▼ │
41+
│ 5. Original tool receives only: { "location": "Paris" } │
42+
│ │
43+
└─────────────────────────────────────────────────────────────────────────┘
44+
```
45+
46+
## Key Components
47+
48+
### AgentThinking Record
49+
50+
Defines the additional arguments to capture from the LLM:
51+
52+
```java
53+
public record AgentThinking(
54+
@ToolParam(description = "Your step-by-step reasoning for why you're calling this tool",
55+
required = true)
56+
String innerThought,
57+
58+
@ToolParam(description = "Confidence level (low, medium, high) in this tool choice",
59+
required = false)
60+
String confidence,
61+
62+
@ToolParam(description = "Key insights to remember for future interactions",
63+
required = true)
64+
List<String> memoryNotes
65+
) {}
66+
```
67+
68+
### AugmentedToolCallbackProvider
69+
70+
Wraps existing tools to transparently augment their schemas:
71+
72+
```java
73+
AugmentedToolCallbackProvider<AgentThinking> provider = AugmentedToolCallbackProvider
74+
.<AgentThinking>builder()
75+
.toolObject(new MyTools())
76+
.argumentType(AgentThinking.class)
77+
.argumentConsumer(event -> {
78+
AgentThinking thinking = event.arguments();
79+
logger.info("LLM Reasoning: {}", thinking.innerThought());
80+
logger.info("Confidence: {}", thinking.confidence());
81+
logger.info("Memory Notes: {}", thinking.memoryNotes());
82+
})
83+
.removeExtraArgumentsAfterProcessing(true)
84+
.build();
85+
```
86+
87+
### Integration with Advisors
88+
89+
Combines tool augmentation with Spring AI's advisor chain:
90+
91+
```java
92+
ChatClient chatClient = chatClientBuilder
93+
.defaultToolCallbacks(provider)
94+
.defaultAdvisors(
95+
ToolCallAdvisor.builder()
96+
.conversationHistoryEnabled(false).build(),
97+
MessageChatMemoryAdvisor.builder(chatMemory).build(),
98+
new MyLogAdvisor())
99+
.build();
100+
```
101+
102+
## Running the Example
103+
104+
### Prerequisites
105+
106+
- Java 17 or higher
107+
- OpenAI API key (or Anthropic API key)
108+
109+
### Configuration
110+
111+
Set your API key as an environment variable:
112+
113+
```bash
114+
export OPENAI_API_KEY=your-api-key
115+
# or
116+
export ANTHROPIC_API_KEY=your-api-key
117+
```
118+
119+
### Build and Run
120+
121+
```bash
122+
cd advisors/recursive-advisor-with-memory
123+
./mvnw spring-boot:run
124+
```
125+
126+
## Sample Output
127+
128+
When running the example, you'll see the LLM's reasoning captured before each tool call:
129+
130+
```
131+
LLM Reasoning: The user is asking about the current weather in Paris. I need to call the weather tool...
132+
Confidence: high
133+
Memory Notes: [User interested in Paris weather, May need follow-up about activities]
134+
Tool: weather
135+
136+
REQUEST: [{"type":"USER","text":"What is current weather in Paris?"}]
137+
138+
RESPONSE: [{"output":{"text":"The current weather in Paris is sunny with a temperature of 25°C."}}]
139+
```
140+
141+
## Use Cases
142+
143+
- **Debugging**: Understand why your AI agent made specific tool choices
144+
- **Observability**: Log and monitor agent reasoning in production
145+
- **Memory Enhancement**: Store insights for improved context in future conversations
146+
- **Multi-Agent Coordination**: Pass coordination signals between agents
147+
- **Analytics**: Track tool usage patterns and decision quality
148+
149+
## Resources
150+
151+
- [Explainable AI Agents Blog Post](https://spring.io/blog/2025/12/21/explainable-ai-agents-capture-llm-tool-call-reasoning-with-spring-ai)
152+
- [Spring AI Tool Calling Documentation](https://docs.spring.io/spring-ai/reference/api/tools.html)
153+
- [Spring AI Advisors Guide](https://docs.spring.io/spring-ai/reference/api/advisors.html)
154+
- [Tool Argument Augmenter](https://docs.spring.io/spring-ai/reference/2.0-SNAPSHOT/api/tools.html#tool-argument-augmentation)

0 commit comments

Comments
 (0)