So sánh ChatClient Middleware và Agent Middleware

Middleware giữ vai trò quan trọng trong việc mở rộng chức năng và khả năng quan sát của agent. Microsoft Agent Framework sử dụng hai loại middleware chính: ChatClient Middleware và Agent Middleware. Hiểu rõ sự khác biệt giữa hai loại này giúp nhà phát triển tối ưu hiệu năng và năng lực của agent.

Bài viết này trình bày sự khác nhau giữa ChatClient Middleware và Agent Middleware, đồng thời minh họa cách chúng hoạt động qua các ví dụ, trong đó có middleware gọi hàm dành cho một agent duy nhất.

Đây là cách được sử dụng trong chương trình minh họa để ghi nhật ký việc gọi công cụ tìm kiếm Tavily.

Middleware là gì?

Middleware là một lớp phần mềm đóng vai trò trung gian giữa các ứng dụng hoặc thành phần phần mềm khác nhau. Trong Microsoft Agent Framework, middleware nâng cao sự tương tác giữa agent và các hệ thống bên dưới, cho phép nhà phát triển chặn, sửa đổi và ghi nhật ký các tin nhắn cũng như thao tác.

Khả năng này đặc biệt hữu ích khi gỡ lỗi, theo dõi hoạt động và mở rộng chức năng của agent.

ChatClient Middleware

Mục đích

ChatClient Middleware được thiết kế để chặn các lệnh gọi đến một phần hiện thực của IChatClient. Loại middleware này phù hợp để ghi nhật ký, sửa đổi hoặc kiểm tra các tin nhắn thô được trao đổi giữa agent và mô hình ngôn ngữ lớn, thường gọi là LLM.

Nhờ ChatClient Middleware, nhà phát triển có thể quan sát luồng giao tiếp. Đây là cơ sở quan trọng để gỡ lỗi và cải thiện hiệu năng của agent.

Trường hợp sử dụng

Một trường hợp sử dụng phổ biến là ghi nhật ký toàn bộ tin nhắn agent gửi đi và nhận về. Thông tin này giúp nhà phát triển hiểu cách agent tương tác với người dùng và LLM, từ đó tối ưu câu trả lời cũng như trải nghiệm tổng thể.

Ví dụ

Dưới đây là ví dụ đơn giản về cách tạo ChatClient Middleware bằng C#:

var chatClient = new AIProjectClient(new Uri("your-uri"), new DefaultAzureCredential())
    .GetProjectOpenAIClient()
    .GetProjectResponsesClient()
    .AsIChatClient(deploymentName);

var middlewareEnabledChatClient = chatClient
    .AsBuilder()
    .Use(getResponseFunc: CustomChatClientMiddleware, getStreamingResponseFunc: null)
    .Build();

Trong ví dụ này, CustomChatClientMiddleware là một hàm xử lý tin nhắn trước khi chúng được gửi đến LLM hoặc sau khi được nhận về. Middleware có thể ghi nhật ký, sửa đổi tin nhắn hoặc thực hiện thêm logic dựa trên nội dung của chúng.

Agent Middleware

Mục đích

Agent Middleware hoạt động ở cấp cao hơn ChatClient Middleware. Nó cho phép chặn toàn bộ các lần chạy của agent, qua đó nhà phát triển có thể kiểm tra và sửa đổi dữ liệu đầu vào cũng như đầu ra trong quá trình agent hoạt động.

Loại middleware này phù hợp để quản lý hành vi tổng thể của agent, bao gồm quản lý phiên, theo dõi danh tính và quản lý ngân sách token.

Trường hợp sử dụng

Một trường hợp điển hình là thu thập thông tin về phiên hoặc danh tính của agent. Chẳng hạn, nếu agent cần duy trì ngữ cảnh qua nhiều lần tương tác hoặc quản lý hiệu quả mức sử dụng tài nguyên, Agent Middleware sẽ là lựa chọn phù hợp.

Ví dụ

Bạn có thể tạo agent bằng ChatClient có bật middleware như sau:

var agent = new ChatClientAgent(
    middlewareEnabledChatClient,
    instructions: "You are a helpful assistant.");

Trong ví dụ này, ChatClientAgent được khởi tạo bằng chat client đã bật middleware. Agent có thể tận dụng khả năng của cả ChatClient Middleware và Agent Middleware để mở rộng chức năng.

Middleware gọi hàm cho một agent

Middleware gọi hàm có thể được áp dụng cho cả ChatClient Middleware và Agent Middleware. Loại middleware này cho phép chặn các lệnh gọi hàm do agent thực hiện, từ đó nhà phát triển có thể kiểm tra và sửa đổi dữ liệu đầu vào cũng như đầu ra.

Khả năng này đặc biệt hữu ích cho việc ghi nhật ký, gỡ lỗi và bổ sung logic dựa trên các thao tác của agent.

Ví dụ về middleware gọi hàm trong C#

Dưới đây là một ví dụ đơn giản:

public class FunctionInvocationMiddleware
{
    public async Task InvokeAsync(
        AgentRunContext context,
        Func<AgentRunContext, Task> next)
    {
        // Trước khi gọi hàm
        Console.WriteLine($"Before function call: {context.FunctionName}");

        // Gọi middleware tiếp theo trong pipeline
        await next(context);

        // Sau khi gọi hàm
        Console.WriteLine($"After the function call: {context.Result}");
    }
}

// Cách sử dụng
var agent = new ChatClientAgent(
        middlewareEnabledChatClient,
        instructions: "You are a helpful assistant.")
    .AsBuilder()
    .Use(FunctionInvocationMiddleware.InvokeAsync)
    .Build();

Trong ví dụ này, lớp FunctionInvocationMiddleware định nghĩa phương thức InvokeAsync để ghi nhật ký tên hàm trước và sau khi hàm được gọi. Middleware giúp theo dõi luồng thực thi của agent và cung cấp thông tin hữu ích về hành vi của agent.

Ghi nhật ký lệnh gọi công cụ Tavily

Trong chương trình minh họa, phần tạo ResearcherAgent được bổ sung đoạn mã sau:

.Use(async (agent, context, next, cancellationToken) =>
{
    if (context.Function.Name == tavilyTool.Name)
    {
        _logger.LogInformation(
            "Researcher invoking Tavily tool '{Tool}' with arguments {Arguments}",
            context.Function.Name,
            context.Arguments);
    }

    return await next(context, cancellationToken);
})

Đây là thay đổi duy nhất cần thiết để middleware ghi nhận các lệnh gọi đến công cụ Tavily của agent nghiên cứu. Những agent khác không cần thay đổi.

Kết quả theo dõi sau thay đổi này có dạng:

[trace] → execute_tool tavily_search
info: BlogWriter.ResearcherAgent[0]
      Researcher invoking Tavily tool 'tavily_search' with arguments [query, ChatClient middleware vs Agent middleware Microsoft Agent Framework]
[trace] ← execute_tool tavily_search (1796 ms)

Tóm tắt

Microsoft Agent Framework cung cấp hai loại middleware riêng biệt: ChatClient Middleware và Agent Middleware.

  • ChatClient Middleware tập trung vào tương tác với chat client, cho phép ghi nhật ký và sửa đổi các tin nhắn trao đổi với LLM.
  • Agent Middleware xử lý các hoạt động tổng thể của agent, cho phép quản lý thông tin phiên, danh tính và mức sử dụng tài nguyên.
  • Middleware gọi hàm có thể được dùng để chặn các lệnh gọi hàm, nhờ đó nhà phát triển kiểm soát chi tiết hơn hành vi của agent.

Lưu ý: Bản nháp ban đầu của bài viết được tạo bởi BlogWriter và sau đó được Jesse Liberty biên tập. Hình minh họa được tạo bằng Copilot. Các mô hình ngôn ngữ vẫn có thể mắc lỗi; nội dung này được cung cấp nguyên trạng.