Reflection Agent Example
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
package org.springframework.ai.openai.samples.helloworld;
|
||||
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
CommandLineRunner cli(ReflectionAgent reflectionAgent) {
|
||||
return args -> {
|
||||
var scanner = new Scanner(System.in);
|
||||
System.out.println("\nLet's chat!");
|
||||
|
||||
// Generate a Java implementation of the Merge Sort algorithm
|
||||
while (true) {
|
||||
System.out.print("\nUSER: ");
|
||||
System.out.println("AGENT: " +
|
||||
reflectionAgent.run(scanner.nextLine(), 2));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2024 - 2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ai.openai.samples.helloworld;
|
||||
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
|
||||
import org.springframework.ai.chat.memory.InMemoryChatMemory;
|
||||
import org.springframework.ai.chat.model.ChatModel;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ReflectionAgent {
|
||||
|
||||
private final ChatClient generateChatClient;
|
||||
|
||||
private final ChatClient critiqueChatClient;
|
||||
|
||||
|
||||
public ReflectionAgent(ChatModel chatModel) {
|
||||
this.generateChatClient = ChatClient.builder(chatModel)
|
||||
.defaultSystem("""
|
||||
You are a Java programmer tasked with generating high quality Java code.
|
||||
Your task is to Generate the best content possible for the user's request. If the user provides critique,
|
||||
respond with a revised version of your previous attempt.
|
||||
""")
|
||||
.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
|
||||
.build();
|
||||
|
||||
this.critiqueChatClient = ChatClient.builder(chatModel)
|
||||
.defaultSystem("""
|
||||
You are tasked with generating critique and recommendations to the user's generated content.
|
||||
If the user content has something wrong or something to be improved, output a list of recommendations
|
||||
and critiques. If the user content is ok and there's nothing to change, output this: <OK>
|
||||
""")
|
||||
.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public String run(String userQuestion, int maxIterations) {
|
||||
|
||||
String generation = generateChatClient.prompt(userQuestion).call().content();
|
||||
System.out.println("##generation\n\n" + generation);
|
||||
String critique;
|
||||
for (int i = 0; i < maxIterations; i++) {
|
||||
|
||||
critique = critiqueChatClient.prompt(generation).call().content();
|
||||
|
||||
System.out.println("##Critique\n\n" + critique);
|
||||
if (critique.contains("<OK>")) {
|
||||
System.out.println("\n\nStop sequence found\n\n");
|
||||
break;
|
||||
}
|
||||
generation = generateChatClient.prompt(critique).call().content();
|
||||
}
|
||||
return generation;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
29
agents/reflection/src/main/resources/application.yaml
Normal file
29
agents/reflection/src/main/resources/application.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
spring:
|
||||
ai:
|
||||
azure:
|
||||
openai:
|
||||
chat:
|
||||
options:
|
||||
function-callbacks:
|
||||
- name: "functionName1"
|
||||
description: "Description of what function1 does"
|
||||
input-type-schema: |
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"param1": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
- name: "functionName2"
|
||||
description: "Description of what function2 does"
|
||||
input-type-schema: |
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"param2": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2024 - 2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ai.openai.samples.helloworld;
|
||||
|
||||
public class MergeSort {
|
||||
|
||||
public static void mergeSort(int[] array) {
|
||||
if (array == null || array.length < 2) {
|
||||
return;
|
||||
}
|
||||
int[] tempArray = new int[array.length];
|
||||
mergeSort(array, tempArray, 0, array.length - 1);
|
||||
}
|
||||
|
||||
private static void mergeSort(int[] array, int[] tempArray, int start, int end) {
|
||||
if (start < end) {
|
||||
int mid = (start + end) / 2;
|
||||
|
||||
// Recursively sort the two halves
|
||||
mergeSort(array, tempArray, start, mid);
|
||||
mergeSort(array, tempArray, mid + 1, end);
|
||||
|
||||
// Merge the sorted halves
|
||||
merge(array, tempArray, start, mid, end);
|
||||
}
|
||||
}
|
||||
|
||||
private static void merge(int[] array, int[] tempArray, int start, int mid, int end) {
|
||||
// Copy data to temporary array for merging
|
||||
System.arraycopy(array, start, tempArray, start, end - start + 1);
|
||||
|
||||
int leftIndex = start;
|
||||
int rightIndex = mid + 1;
|
||||
int currentIndex = start;
|
||||
|
||||
// Merge the temp arrays back into the original array
|
||||
while (leftIndex <= mid && rightIndex <= end) {
|
||||
if (tempArray[leftIndex] <= tempArray[rightIndex]) {
|
||||
array[currentIndex] = tempArray[leftIndex];
|
||||
leftIndex++;
|
||||
} else {
|
||||
array[currentIndex] = tempArray[rightIndex];
|
||||
rightIndex++;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
// Copy remaining elements of left half, if any
|
||||
while (leftIndex <= mid) {
|
||||
array[currentIndex] = tempArray[leftIndex];
|
||||
leftIndex++;
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
// No need to copy the right half because it's already in place
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[][] testCases = {
|
||||
{12, 11, 13, 5, 6, 7},
|
||||
{5, 5, 5, 5, 5, 5},
|
||||
{},
|
||||
{-1, -3, -2, -5, -4},
|
||||
{1, 2, 3, 4, 5, 6},
|
||||
{9, 7, 5, 3, 1, 0}
|
||||
};
|
||||
|
||||
for (int i = 0; i < testCases.length; i++) {
|
||||
System.out.println("Test Case " + (i + 1) + ":");
|
||||
System.out.println("Original Array:");
|
||||
printArray(testCases[i]);
|
||||
|
||||
mergeSort(testCases[i]);
|
||||
|
||||
System.out.println("Sorted Array:");
|
||||
printArray(testCases[i]);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private static void printArray(int[] array) {
|
||||
for (int value : array) {
|
||||
System.out.print(value + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.springframework.ai.openai.samples.helloworld;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ResultFromAgentTest {
|
||||
|
||||
@Test
|
||||
void testMergeSortWithRandomArray() {
|
||||
int[] array = {12, 11, 13, 5, 6, 7};
|
||||
int[] expected = {5, 6, 7, 11, 12, 13};
|
||||
|
||||
MergeSort.mergeSort(array);
|
||||
assertArrayEquals(expected, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergeSortWithAllSameElements() {
|
||||
int[] array = {5, 5, 5, 5, 5};
|
||||
int[] expected = {5, 5, 5, 5, 5};
|
||||
|
||||
MergeSort.mergeSort(array);
|
||||
assertArrayEquals(expected, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergeSortWithEmptyArray() {
|
||||
int[] array = {};
|
||||
int[] expected = {};
|
||||
|
||||
MergeSort.mergeSort(array);
|
||||
assertArrayEquals(expected, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergeSortWithNegativeNumbers() {
|
||||
int[] array = {-1, -3, -2, -5, -4};
|
||||
int[] expected = {-5, -4, -3, -2, -1};
|
||||
|
||||
MergeSort.mergeSort(array);
|
||||
assertArrayEquals(expected, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergeSortWithAlreadySortedArray() {
|
||||
int[] array = {1, 2, 3, 4, 5, 6};
|
||||
int[] expected = {1, 2, 3, 4, 5, 6};
|
||||
|
||||
MergeSort.mergeSort(array);
|
||||
assertArrayEquals(expected, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergeSortWithReverseSortedArray() {
|
||||
int[] array = {9, 7, 5, 3, 1, 0};
|
||||
int[] expected = {0, 1, 3, 5, 7, 9};
|
||||
|
||||
MergeSort.mergeSort(array);
|
||||
assertArrayEquals(expected, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergeSortWithNullArray() {
|
||||
int[] array = null;
|
||||
|
||||
// Should not throw an exception
|
||||
assertDoesNotThrow(() -> MergeSort.mergeSort(array));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMergeSortWithSingleElement() {
|
||||
int[] array = {1};
|
||||
int[] expected = {1};
|
||||
|
||||
MergeSort.mergeSort(array);
|
||||
assertArrayEquals(expected, array);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user