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
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-03-16,如有侵权请联系 cloudcommunity@tencent 删除stringjavaagentdate

本文标签: 聊聊langchain4j的Agent