admin管理员组文章数量:1446760
聊聊langchain4j的Agent
序
本文主要研究一下langchain4j的Agent
示例
CustomerSupportAgent
customer-support-agent-example/src/main/java/dev/langchain4j/example/CustomerSupportAgent.java
代码语言:javascript代码运行次数:0运行复制@AiService
public interface CustomerSupportAgent {
@SystemMessage("""
Your name is Roger, you are a customer support agent of a car rental company named 'Miles of Smiles'.
You are friendly, polite and concise.
Rules that you must obey:
1. Before getting the booking details or canceling the booking,
you must make sure you know the customer's first name, last name, and booking number.
2. When asked to cancel the booking, first make sure it exists, then ask for an explicit confirmation.
After cancelling the booking, always say "We hope to welcome you back again soon".
3. You should answer only questions related to the business of Miles of Smiles.
When asked about something not relevant to the company business,
apologize and say that you cannot help with that.
Today is {{current_date}}.
""")
Result<String> answer(@MemoryId String memoryId, @UserMessage String userMessage);
}
CustomerSupportAgent定义了SystemMessage、memoryId、userMessage
CustomerSupportAgentIT
customer-support-agent-example/src/test/java/dev/langchain4j/example/CustomerSupportAgentIT.java
代码语言:javascript代码运行次数:0运行复制 @Test
void should_provide_booking_details_for_existing_booking() {
// given
String userMessage = "Hi, I am %s %s. When does my booking %s start?"
.formatted(CUSTOMER_NAME, CUSTOMER_SURNAME, BOOKING_NUMBER);
// when
Result<String> result = agent.answer(memoryId, userMessage);
String answer = result.content();
// then
assertThat(answer)
.containsIgnoringCase(getDayFrom(BOOKING_BEGIN_DATE))
.containsIgnoringCase(getMonthFrom(BOOKING_BEGIN_DATE))
.containsIgnoringCase(getYearFrom(BOOKING_BEGIN_DATE));
assertThat(result).onlyToolWasExecuted("getBookingDetails");
verify(bookingService).getBookingDetails(BOOKING_NUMBER, CUSTOMER_NAME, CUSTOMER_SURNAME);
verifyNoMoreInteractions(bookingService);
TokenUsage tokenUsage = result.tokenUsage();
assertThat(tokenUsage.inputTokenCount()).isLessThan(1000);
assertThat(tokenUsage.outputTokenCount()).isLessThan(200);
with(judgeModel).assertThat(answer)
.satisfies("mentions that booking starts on %s".formatted(BOOKING_BEGIN_DATE));
}
@Test
void should_not_provide_booking_details_when_booking_does_not_exist() {
// given
String invalidBookingNumber = "54321";
String userMessage = "Hi, I am %s %s. When does my booking %s start?"
.formatted(CUSTOMER_NAME, CUSTOMER_SURNAME, invalidBookingNumber);
// when
Result<String> result = agent.answer(memoryId, userMessage);
String answer = result.content();
// then
assertThat(answer)
.doesNotContainIgnoringCase(getDayFrom(BOOKING_BEGIN_DATE))
.doesNotContainIgnoringCase(getMonthFrom(BOOKING_BEGIN_DATE))
.doesNotContainIgnoringCase(getYearFrom(BOOKING_BEGIN_DATE));
assertThat(result).onlyToolWasExecuted("getBookingDetails");
verify(bookingService).getBookingDetails(invalidBookingNumber, CUSTOMER_NAME, CUSTOMER_SURNAME);
verifyNoMoreInteractions(bookingService);
with(judgeModel).assertThat(answer).satisfies(
"mentions that booking cannot be found",
"does not mention any dates"
);
}
@Test
void should_not_provide_booking_details_when_not_enough_data_is_provided() {
// given
String userMessage = "When does my booking %s start?".formatted(BOOKING_NUMBER); // name and surname are not provided
// when
Result<String> result = agent.answer(memoryId, userMessage);
String answer = result.content();
// then
assertThat(answer)
.doesNotContainIgnoringCase(getDayFrom(BOOKING_BEGIN_DATE))
.doesNotContainIgnoringCase(getMonthFrom(BOOKING_BEGIN_DATE))
.doesNotContainIgnoringCase(getYearFrom(BOOKING_BEGIN_DATE));
assertThat(result).noToolsWereExecuted();
with(judgeModel).assertThat(answer).satisfies(
"asks user to provide their name and surname",
"does not mention any dates"
);
}
// cancelling booking
@Test
void should_cancel_booking() {
// given
String userMessage = "Cancel my booking %s. My name is %s %s."
.formatted(BOOKING_NUMBER, CUSTOMER_NAME, CUSTOMER_SURNAME);
// when
Result<String> result = agent.answer(memoryId, userMessage);
// then
assertThat(result).onlyToolWasExecuted("getBookingDetails");
verify(bookingService).getBookingDetails(BOOKING_NUMBER, CUSTOMER_NAME, CUSTOMER_SURNAME);
verifyNoMoreInteractions(bookingService);
with(judgeModel).assertThat(result.content())
.satisfies("is asking for the confirmation to cancel the booking");
// when
Result<String> result2 = agent.answer(memoryId, "yes, cancel it");
// then
assertThat(result2.content()).containsIgnoringCase("We hope to welcome you back again soon");
assertThat(result2).onlyToolWasExecuted("cancelBooking");
verify(bookingService).cancelBooking(BOOKING_NUMBER, CUSTOMER_NAME, CUSTOMER_SURNAME);
verifyNoMoreInteractions(bookingService);
}
小结
Agent这个词比较宽泛,而且有很多不同的定义,通常基本的agentic的功能可以基于high-level的AI Service和Tool来构建,如果还需要更灵活的设置,则可以基于low-level的ChatLanguageModel、ToolSpecification以及ChatMemory APIs来构建。langchain4j目前暂不支持类似AutoGen或CrewAI中用于构建多智能体系统的"Agent"高级抽象功能,如果需要则可以基于low-level的API去构建。
doc
- agents
- CustomerSupportAgentIT
本文标签: 聊聊langchain4j的Agent
版权声明:本文标题:聊聊langchain4j的Agent 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1748253736a2832748.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论