����λ�ã���ҳ > �����̳� > �̳� > ��Ƚ���Spring AI����������Ӧ���Ƶĺ����߼�
������ǰ��������½��л����϶�Spring Boot 3�汾���±仯������ȫ��Ļعˣ���ȷ���ڽ������о�Spring AIʱ�ܹ������κ�DZ�ڵ����⡣���죬�������ڿ���ֱ�ӽ������⣺Spring AI����η������󲢽���Ϣ���ظ��û��ġ� �ڽ������������У����ǽ�רע����һ���̣�����ʽ�ش�ͺ����ص�����
������ǰ��������½��л����϶�Spring Boot 3�汾���±仯������ȫ��Ļعˣ���ȷ���ڽ������о�Spring AIʱ�ܹ������κ�DZ�ڵ����⡣���죬�������ڿ���ֱ�ӽ������⣺Spring AI����η������󲢽���Ϣ���ظ��û��ġ�
�ڽ������������У����ǽ�רע����һ���̣�����ʽ�ش�ͺ����ص�������������ǿ������´εĽ�������ϸ̽�֡�
���ȣ����ڻ�û����Ŀ��ͬѧ������ذ�װ�����POM�������ע�⣬JDK�İ汾Ҫ��Ϊ17����ˣ��������IDEA���������غ���������汾��
http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
3.3.1
com.example
demo
0.0.1-SNAPSHOT
demo
Demo project for Spring Boot
17
1.0.0-M2
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-web
org.springframework.ai
spring-ai-openai-spring-boot-starter
com.github.xiaoymin
knife4j-openapi3-jakarta-spring-boot-starter
4.1.0
javax.servlet
javax.servlet-api
4.0.1
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.ai
spring-ai-bom
${spring-ai.version}
pom
import
org.graalvm.buildtools
native-maven-plugin
${project.artifactId}
com.example.demo.DemoApplication
--no-fallback
build-native
compile-no-fork
package
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
�����÷���֮ǰ�Ľ������Ѿ����ǹ����������Ͳ�����ϸ˵����Ϊ�˸��õ�������һ������ǽ�ͨ�����������������������ʾ��
��һ�����ӽ�չʾ�����ش��ʵ�֣����ڶ�����������漰������������Ϣ����Ļش������ַ�ʽ���������Ǹ�������˽������ʵ��Ӧ�������������Щ������
���ォ�ṩһ�������ش���÷�ʾ�����Ա���õ�������Ӧ�ó����;���ʵ�ַ�ʽ��
@PostMapping("/ai")
ChatDataPO generationByText(@RequestParam("userInput") String userInput) {
String content = this.myChatClientWithSystem.prompt()
.user(userInput)
.call()
.content();
log.info("content: {}", content);
ChatDataPO chatDataPO = ChatDataPO.builder().code("text").data(ChildData.builder().text(content).build()).build();;
return chatDataPO;
}
�����ʾ���У����ǽ�չʾ���ʵ��һ���ȴ� AI ��ɻش�Ļ��ƣ��������ֱ�ӷ��ظ��ӿڵ��öˡ���һ����ʵ���Ϸdz��򵥣���ֻ�轫���⴫�ݸ�
user
�������ɡ������������ǽ�����Դ�������
Ϊ�˽�ʡʱ�䣬���Dz�����ϸ���з����м���̵Ĵ��룬��Ϊ����ܻ��Ե��߳������ӡ��෴�����ǽ�ֱ�Ӿ۽��ڹؼ�Դ�룬�Ա����Ч������������߼���ʵ��ϸ�ڡ�
��������ֱ�ӽ���
content
�������������������ǰ��IJ����У����з����IJ���������Ҫ��Ϊ�˹���һ������Ϊ�����IJ�����׼�����������ĺ��ĵ����߼�������
content
�����ڲ���
private ChatResponse doGetChatResponse(DefaultChatClientRequestSpec inputRequest, String formatParam) {
Map context = new ConcurrentHashMap<>();
context.putAll(inputRequest.getAdvisorParams());
DefaultChatClientRequestSpec advisedRequest = DefaultChatClientRequestSpec.adviseOnRequest(inputRequest,
context);
var processedUserText = StringUtils.hasText(formatParam)
? advisedRequest.getUserText() + System.lineSeparator() + "{spring_ai_soc_format}"
: advisedRequest.getUserText();
Map userParams = new HashMap<>(advisedRequest.getUserParams());
if (StringUtils.hasText(formatParam)) {
userParams.put("spring_ai_soc_format", formatParam);
}
var messages = new ArrayList(advisedRequest.getMessages());
var textsAreValid = (StringUtils.hasText(processedUserText)
|| StringUtils.hasText(advisedRequest.getSystemText()));
if (textsAreValid) {
if (StringUtils.hasText(advisedRequest.getSystemText())
|| !advisedRequest.getSystemParams().isEmpty()) {
var systemMessage = new SystemMessage(
new PromptTemplate(advisedRequest.getSystemText(), advisedRequest.getSystemParams())
.render());
messages.add(systemMessage);
}
UserMessage userMessage = null;
if (!CollectionUtils.isEmpty(userParams)) {
userMessage = new UserMessage(new PromptTemplate(processedUserText, userParams).render(),
advisedRequest.getMedia());
}
else {
userMessage = new UserMessage(processedUserText, advisedRequest.getMedia());
}
messages.add(userMessage);
}
if (advisedRequest.getChatOptions() instanceof FunctionCallingOptions functionCallingOptions) {
if (!advisedRequest.getFunctionNames().isEmpty()) {
functionCallingOptions.setFunctions(new HashSet<>(advisedRequest.getFunctionNames()));
}
if (!advisedRequest.getFunctionCallbacks().isEmpty()) {
functionCallingOptions.setFunctionCallbacks(advisedRequest.getFunctionCallbacks());
}
}
var prompt = new Prompt(messages, advisedRequest.getChatOptions());
var chatResponse = this.chatModel.call(prompt);
ChatResponse advisedResponse = chatResponse;
// apply the advisors on response
if (!CollectionUtils.isEmpty(inputRequest.getAdvisors())) {
var currentAdvisors = new ArrayList<>(inputRequest.getAdvisors());
for (RequestResponseAdvisor advisor : currentAdvisors) {
advisedResponse = advisor.adviseResponse(advisedResponse, context);
}
}
return advisedResponse;
}
��δ���û���κ�ע�ͣ�ȷʵ���˸е����⣬���˵����Spring�������Ƴ��ԡ���������Ϊ���������ã�����Ϊ�����Ķ��������˼���ǣ��ܹ���Чʹ�þ��㹻�ˡ�������δ����Եü�����ˣ�������Ҫ�Բ��ݺ��ӡ����е�ʵ�ֶ��dz�������û������Ĵ��룬����Ҿ���������ɾ�������ǽ����������ֳ�����
Ϊ�˰�����Ҹ��õ��������е��߼��ͽṹ���ҽ�ʹ��α���������н��⡣
��ʼ�������� ������һ���յ������ġ�
�������
������������߼��ǻ��������Ķ�����������ж�̬���������ȣ�������Ҫ�ж���������Ƿ��Ѿ���
advisor
��װ�������Ҫ��ô���ǽ�����һ������
advisor
��װ����������
��������ص�Դ��ʵ�֣�չʾ����һ�߼��ľ���ϸ�ڣ�
public static DefaultChatClientRequestSpec adviseOnRequest(DefaultChatClientRequestSpec inputRequest,
Map context) {
//....�˴�ʡ��һ�Ѵ���
var currentAdvisors = new ArrayList<>(inputRequest.advisors);
for (RequestResponseAdvisor advisor : currentAdvisors) {
adviseRequest = advisor.adviseRequest(adviseRequest, context);
}
advisedRequest = new DefaultChatClientRequestSpec(adviseRequest.chatModel(), adviseRequest.userText(),
adviseRequest.userParams(), adviseRequest.systemText(), adviseRequest.systemParams(),
adviseRequest.functionCallbacks(), adviseRequest.messages(), adviseRequest.functionNames(),
adviseRequest.media(), adviseRequest.chatOptions(), adviseRequest.advisors(),
adviseRequest.advisorParams(), inputRequest.getObservationRegistry(),
inputRequest.getCustomObservationConvention());
}
return advisedRequest;
}
�����������ϸ����һ��
advisor.adviseRequest(adviseRequest, context)
��һ�����Ĺ��ܺ���Ҫ�ԡ����������Ѿ���������ǿ�࣬����������һ��������书�ܣ��÷��������þ��Ե���Ϊ�ؼ���������˵��������Դ�������������ǿ�������������ض���ҵ������
ֵ��ע����ǣ������ǿ����ķ���������ǿ��Ӧ�������Ӧ�ģ�����ͨ���ɶԳ��֡�������������鿴
adviseRequest
�����ľ���ʵ�֣�
String content = this.myChatClientWithSystem.prompt()
.advisors(new MessageChatMemoryAdvisor(chatMemory))
.user(userInput)
.call()
.content();
����������
MessageChatMemoryAdvisor
�࣬����ķ����ľ���ʵ���ǣ��ڽ��յ���Ӧ����Ϣ�󣬽�����Ϣ�洢��һ����������С�����һ������һ�δ�������ʱ���Ϳ���ֱ�Ӵ������������ȡ������ݡ�
public AdvisedRequest adviseRequest(AdvisedRequest request, Map context) {
//�˴�ʡ��һ�Ѵ���
// 4. Add the new user input to the conversation memory.
UserMessage userMessage = new UserMessage(request.userText(), request.media());
this.getChatMemoryStore().add(this.doGetConversationId(context), userMessage);
return advisedRequest;
}
�����û��ı��������û�����
����Ҫ����
formatParam
���������û���������д�����������ԣ�������費���漰�����û��ı��ĸ�ʽ��������Ҫ������Ӧ���û�������
�����������ǽ�չʾ�����ʵ��ʾ�����Ա��������������һ���̵IJ���ϸ�ڣ�
.user(u -> u.text("""
Generate the filmography for a random actor.
{format}
""")
.param("format", converter.getFormat()))
����Ĵ���λὫ
{format}
�滻Ϊʵ�ʵĸ�ʽ����Ϣ�������û��ṩ�IJ����⣬ϵͳ��Ϣ��ͬ��������һЩ��Ҫ�����IJ�������Щ����Ҳ�����ڴ�����������ȷ�ش��롣
������Ϣ�б� ������ϵͳ�ı����û��ı�����Ч�ԣ�������Ϣ�Ĺ��̽����߽������ϡ����ǿ��Խ�������Ч����Ϣ���ӵ�һ�� List �����У��Ա��ں������������⣬ϵͳ���ᴴ��һ����Ϣ�������ڱ�����Щ��Ϣ�������Ϣ����ȷ������Ҫʱ���Է���ط��ʺ͹������ǡ�
�Ƿ��к����ص� ������У�������һ�¾���ĺ���������һ�½�ϸ����
����������ʾ ������һ����ʾnew Prompt()���󲢵�������ģ��api��ȡ������Ϣ��
������ǿ �������ǰ������������� advisor����ô���������Ӧ����ǿ���������⣬ϵͳ���Զ�����Ӧ���ʴ����ݴ洢����Ϣ�б��У������Ӧ����ϢҲ��Ҫ��һ����¼������
public ChatResponse adviseResponse(ChatResponse chatResponse, Map context) {
List assistantMessages = chatResponse.getResults().stream().map(g -> (Message) g.getOutput()).toList();
this.getChatMemoryStore().add(this.doGetConversationId(context), assistantMessages);
return chatResponse;
}
���ؽ�� ���������յ�������Ӧ��
�����������ǽ���ϸ̽�����ͨ��������������� OpenAI �ӿڵľ�����̡�Ϊ�ˣ����ǽ��� OpenAI ��Դ��Ϊ�������з����������ʹ�õ������� AI ��Ʒ����ô����һ���ڵ����̽���������ͬ��ϵͳ����ݾ���IJ�Ʒ������Ӧ����ת����ͼ��ʾ��
���ǽ��� OpenAI ��������ù��̽���ȫ��Ľ����������������䱳��Ļ��ƺ�ʵ��ϸ�ڣ�
public ChatResponse call(Prompt prompt) {
ChatCompletionRequest request = createRequest(prompt, false);
ChatModelObservationContext observationContext = ChatModelObservationContext.builder()
.prompt(prompt)
.provider(OpenAiApiConstants.PROVIDER_NAME)
.requestOptions(buildRequestOptions(request))
.build();
ChatResponse response = ChatModelObservationDocumentation.CHAT_MODEL_OPERATION
.observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> observationContext,
this.observationRegistry)
.observe(() -> {
ResponseEntity completionEntity = this.retryTemplate
.execute(ctx -> this.openAiApi.chatCompletionEntity(request, getAdditionalHttpHeaders(prompt)));
var chatCompletion = completionEntity.getBody();
if (chatCompletion == null) {
logger.warn("No chat completion returned for prompt: {}", prompt);
return new ChatResponse(List.of());
}
List choices = chatCompletion.choices();
if (choices == null) {
logger.warn("No choices returned for prompt: {}", prompt);
return new ChatResponse(List.of());
}
List generations = choices.stream().map(choice -> {
// @formatter:off
Map metadata = Map.of(
"id", chatCompletion.id() != null ? chatCompletion.id() : "",
"role", choice.message().role() != null ? choice.message().role().name() : "",
"index", choice.index(),
"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "",
"refusal", StringUtils.hasText(choice.message().refusal()) ? choice.message().refusal() : "");
// @formatter:on
return buildGeneration(choice, metadata);
}).toList();
// Non function calling.
RateLimit rateLimit = OpenAiResponseHeaderExtractor.extractAiResponseHeaders(completionEntity);
ChatResponse chatResponse = new ChatResponse(generations, from(completionEntity.getBody(), rateLimit));
observationContext.setResponse(chatResponse);
return chatResponse;
});
if (response != null && isToolCall(response, Set.of(OpenAiApi.ChatCompletionFinishReason.TOOL_CALLS.name(),
OpenAiApi.ChatCompletionFinishReason.STOP.name()))) {
var toolCallConversation = handleToolCalls(prompt, response);
// Recursively call the call method with the tool call message
// conversation that contains the call responses.
return this.call(new Prompt(toolCallConversation, prompt.getOptions()));
}
return response;
}
��Ȼ��Щ���ݶ����м�ֵ��ɾ��������һ���õ�ѡ�񣬵�����ȱ��ע�ͣ����ǿ�����Ҫ��ϸ������������һ����������Щ��Ϣ�����������е��߼���Ҫ�㡣
createRequest
��������Ҫ�����ǹ�����ʵ�ʵ��� API ʱ���������������ڲ�ͬ�����ṩ�̵Ľӿ���Ƹ����ص㣬���������Ҫ���ݾ���� API �淶����ʵ����һ���̡����磬�ڵ��� OpenAI �Ľӿ�ʱ��������Ҫ�����ض��IJ����ṹ����һ���̴��Ӧ���Ѿ��dz���Ϥ������ͼ��ʾ�����ǿ��Կ�����������ʱ����ĸ�����������ʽ��
ChatModelObservationContext
��Ҫ����������������ص��������ƺ�Ҫ�����������ؼ����������籾���������� token �������ơ���ʹ�õ� OpenAI �ʴ�ģ�͵ľ������͡��Լ������Ƶ�����Ƶȡ��������ʾ��
private ChatOptions buildRequestOptions(OpenAiApi.ChatCompletionRequest request) {
return ChatOptionsBuilder.builder()
.withModel(request.model())
.withFrequencyPenalty(request.frequencyPenalty())
.withMaxTokens(request.maxTokens())
.withPresencePenalty(request.presencePenalty())
.withStopSequences(request.stop())
.withTemperature(request.temperature())
.withTopP(request.topP())
.build();
}
ʣ�µ� ChatResponse �󷽷�����ʵ��ִ�� API ���󲢴�����Ӧ������һ�����У��м����ؼ�ϸ��ֵ��ע�⡣
�������ʹ�õ���
retryTemplate
������һ���������Ի��Ƶ����� API ���ߡ��������ּ����ǿ����Ŀɿ��ԣ��ر����������ʱ�Թ��ϻ���������ʱ���ܹ��Զ��������ԣ��Ӷ���߳ɹ��ʡ���Ϊ�����ǣ�
retryTemplate
�����û��������ã������㲻ͬӦ�ó���������
�û����Ը���ʵ����Ҫ�������Դ��������Լ��ʱ���Լ�������ز�����������Щ���ö�����ͨ��
spring.ai.retry
��һǰ׺�����Զ������á������ҿ��Կ�����ࣺ
@AutoConfiguration
@ConditionalOnClass(RetryTemplate.class)
@EnableConfigurationProperties({ SpringAiRetryProperties.class })
public class SpringAiRetryAutoConfiguration {
//�˴�ʡ��һ�Ѵ���
}
���ţ���� OpenAI �Ľӿ�����������Ӧ����ôϵͳ����ʼ��ʽ���ش�����һ�����У��漰������ؼ��ֶΣ���Щ�ֶζ��ڳ���Ա�Ƕ���Ӧ�ö����൱��Ϥ�ģ���������Щ�й��ӿڶԽӾ���Ŀ����ߡ�
Map metadata = Map.of(
"id", chatCompletion.id() != null ? chatCompletion.id() : "",
"role", choice.message().role() != null ? choice.message().role().name() : "",
"index", choice.index(),
"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "",
"refusal", StringUtils.hasText(choice.message().refusal()) ? choice.message().refusal() : "");
���ţ��ڽ��յ����з��ز�����ϵͳ����Щ�������ϲ����ظ�
response
����Ȼ��������һ�׶Σ������ֽ�����һ����Ҫ���жϣ�����Ƿ�Ϊ
isToolCall
������ж�ʵ�����漰�������ص��Ļ��ƣ���һ���ֵ�ʵ���߼��dz��ؼ������������ǾͲ�����̽�����ϸ�ڣ������´��ٽ��н��⡣
���ˣ��������������Ѿ�Բ����ɡ����ǵĽӿ�˳�������ؽ����������Ϣ���ظ��˵��öˣ�ȷ�����û�����ĸ�Ч��Ӧ��
�����̽���У����Ǿ۽���Spring AI�����Ч�ط������󲢽���Ӧ��Ϣ���ݸ��û�����һ���̲����ǿ�������AI�����������������Ż��û�����Ĺؼ���ͨ����ȷ������ṹ����Ӧ���ƣ�Spring AI�ܹ����ش��������û����룬�����������ĵ����ش���ԡ�
Ȼ�����������������һ���Ƶĺ��ģ���ע����ʵ����ҵ���߼����ڴ˹����У�����ͨ��ʵ����ʾ�����ش���������ļ���Ļش������ʵ��Ӧ���з������á�������ʵ�ٲ����ܰ������Ǹ��õ�����Spring AI����Ô����ҲΪ��������̽����ʽ�ش�ͺ����ص������˷��ʡ�
������һ���̵ı����߼�����Ϊ�������ճ�������Ӧ��Spring AI�ṩ����֧�֡����ż����IJ��Ͻ����������������ٵ���սҲ���������ӣ���ͨ��������������������Ӧ�ܹ������ǿ��Ը����ݵ�Ӧ�Ը����ԣ�ʵ�ָ������ܻ��Ľ��������
����Ŭ����С�꣬һ�� Java �������ũ��DZ���о��� AI �����İ��ء����Ȱ�����������������Կ�Դ�����������顣ͬʱҲ��һλ��Ѷ�ƴ���֮�ǡ�������ר�Ҳ�������Ϊ������ר�ҡ�����������ߡ�
? �ҽ����߷������ڼ�����·�ϵĸ���̽���ë¾ï¿½é£¬Ï£ï¿½ï¿½ï¿½ï¿½Îªï¿½ï¿½ï¿½Ñ§Ï°ï¿½ï¿½É³ï¿½ï¿½ï¿½ï¿½ï¿½Ò»Ð©ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
? ��Ó��עŬ����С�꣡?
ʹ��Blender���ɳ���ģ��
�Ķ�ȫ����������ERA5�����ط���
�Ķ�Xpath���������﷨
�Ķ�����ѧϰ�������繹�����£�
�Ķ���ΪMateƷ��ʢ�䣺HarmonyOS NEXT�ӳ�����Ϸ���ܵõ�����ͷ�
�Ķ�ʵ�ֶ��󼯺���DataTable���໥ת��
�Ķ�Ӳ�̵Ļ���֪ʶ��ѡ��ָ��
�Ķ�������й��ƶ��ı�ͼ��ײ�
�Ķ�����NEXTԪ�����������ѿ����ϼ���Ʒ
�Ķ��ᳲ���С������������Ƽ��رշ���
�Ķ������ArcMap�����н���դ��ͼ���ز�������
�Ķ��㷨�����ݽṹ 1 - ģ��
�Ķ���Ѷ�����߿ͷ���Ӫ��ϵͳ����
�Ķ���Ѷ��Ƶҹ��ģʽ���ý̳�
�Ķ����ں���NEXT��Ѫ���Ŵ���������������
�Ķ�5. Spring Cloud OpenFeign ����ʽ WebService �ͻ��˵ij���ϸʹ��
�Ķ�Java����ģʽ����̬�����Ͷ�̬�����ĶԱȷ���
�Ķ�Win11�ʼDZ����Զ�����Ӧ�õ���ɫ����ʾ����
�Ķ�˼�� V1.5.6 ��׿��
��ս�귨 V7.5.0 ��׿��
У��������������׵������� V1.0 ��׿��
��˸֮�� V1.9.7 ��׿��
������Ե����� v1.0.4 ��׿��
������֮ŠV5.2.3 ��׿��
��������������Դ V1.0 ��׿��
���֮Ϣ V1.0 ��׿��
��ħ������������䣩 V1.0 ��׿��
���ں�������ϵ�����������������վ�����������������Ƽ�����
Ƶ�� ����Ƶ��������ר������������׿�������app����
�Ƽ� ��Ô���������°��������ܿ������ز���
���� ����ɫ������������ ���������ս������������
ɨ��ά�����������ֻ��汾��
ɨ��ά����������΢�Ź��ںţ�
��վ�������������������ϴ��������ַ���İ�Ȩ���뷢�ʼ�[email protected]
��ICP��2022002427��-10 �湫��������43070202000427��© 2013~2025 haote.com ������