1. Giới thiệu về OpenAI's Assistants API

1.1 Định nghĩa và Mục đích của Assistants API

Assistants API cho phép các nhà phát triển xây dựng trợ lý trí tuệ nhân tạo trong ứng dụng của họ. Bằng cách xác định các lệnh tùy chỉnh và lựa chọn mô hình, trợ lý có thể sử dụng các mô hình, công cụ và kiến thức để đáp ứng các truy vấn của người dùng. Hiện tại, Assistants API hỗ trợ ba loại công cụ: Code Interpreter, Retrieval và Function Calling.

1.2 Ứng dụng của Assistants API

Assistants API phù hợp cho các kịch bản khác nhau yêu cầu hỗ trợ trí tuệ nhân tạo tương tác. Ví dụ:

  • Hỗ trợ Khách hàng: Tự động trả lời các câu hỏi phổ biến để giảm công việc của dịch vụ khách hàng.
  • Giáo dục Trực tuyến: Trả lời câu hỏi của học sinh và cung cấp hỗ trợ học tập cá nhân hóa.
  • Phân Tích Dữ Liệu: Phân tích các tệp dữ liệu được tải lên bởi người dùng, tạo ra báo cáo và minh họa biểu đồ.
  • Gợi ý Cá Nhân hóa: Cung cấp các gợi ý và dịch vụ cá nhân hóa dựa trên các tương tác lịch sử của người dùng.

1.3 Các Khái niệm Cốt lõi của Assistants

Các đối tượng cốt lõi của Assistants API bao gồm Assistant, Thread và Message. Dưới đây là sự giới thiệu chi tiết về các đối tượng này và chức năng của chúng:

Assistant

Đối tượng Assistant được xây dựng dựa trên các mô hình của OpenAI và có thể gọi các công cụ trợ lý trí tuệ nhân tạo. Bạn có thể tùy chỉnh hướng dẫn của Assistant để cá nhân hóa tính cách và chức năng của nó. Ví dụ, bạn có thể tạo một Assistant có tên "Data Analyst" để phân tích dữ liệu và tạo ra biểu đồ bằng công cụ "code_interpreter".

Thread

Đối tượng Thread đại diện cho phiên trò chuyện giữa người dùng và Assistant. Bạn có thể tạo một Thread cho mỗi người dùng và thêm các tin nhắn vào đó khi người dùng tương tác với Assistant. Đối tượng Thread lưu trữ lịch sử tin nhắn một cách hiệu quả và cắt ngắn các tin nhắn khi cần thiết để tuân thủ giới hạn độ dài ngữ cảnh của mô hình.

Message

Đối tượng Message có thể được tạo ra bởi người dùng hoặc Assistant. Các tin nhắn có thể chứa văn bản, hình ảnh và các tệp khác. Các tin nhắn được lưu trữ dưới dạng một danh sách trên Thread. Trong việc sử dụng thực tế của API, các nhà phát triển có thể thêm tin nhắn của người dùng vào Thread và kích hoạt phản ứng từ Assistant khi cần thiết.

Run

Đối tượng Run đại diện cho việc thực thi một yêu cầu của trợ lý, gọi trợ lý dựa trên nội dung tin nhắn trong Thread. Trợ lý sử dụng cấu hình của mình và các tin nhắn của Thread để thực hiện các nhiệm vụ bằng cách gọi mô hình và công cụ. Là một phần của quá trình thực thi, trợ lý thêm tin nhắn vào Thread.

2. Quá trình Phát triển của Assistants API

2.1 Tạo Trợ lý của bạn

Để tạo một Trợ lý, bạn cần gửi yêu cầu đến API với các hướng dẫn, tên mô hình và cấu hình công cụ. Dưới đây là một ví dụ đơn giản về việc tạo một trợ lý giáo viên toán học cá nhân:

curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "Bạn là một giáo viên toán học cá nhân. Viết và chạy mã để trả lời các câu hỏi toán học.",
    "name": "Giáo Viên Toán",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4"
  }'

Các tham số API:

  • instructions: hướng dẫn hệ thống cho trợ lý làm gì.
  • name: tên của trợ lý.
  • tools: xác định các công cụ mà trợ lý có thể sử dụng. Mỗi trợ lý có thể có tối đa 128 công cụ. Các loại công cụ hiện tại có thể là code_interpreter, retrieval, hoặc function.
  • model: trợ lý sẽ sử dụng mô hình nào?

Sau khi tạo thành công Trợ lý, bạn sẽ nhận được một mã ID của Trợ lý.

2.2 Tạo Một Thread Phiên

Một Thread đại diện cho một cuộc trò chuyện, và chúng tôi khuyến nghị tạo một Thread phiên cho mỗi người dùng khi họ bắt đầu một cuộc trò chuyện. Bạn có thể tạo một Thread như sau:

curl https://api.openai.com/v1/threads \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d ''

Sau khi tạo Thread, bạn sẽ nhận được một mã ID của Thread.

2.3 Thêm Tin Nhắn vào Chủ Đề

Bạn có thể thêm các tin nhắn vào một Chủ Đề cụ thể, chứa văn bản và tùy chọn cho phép người dùng tải lên các tệp. Ví dụ:

curl https://api.openai.com/v1/threads/{thread_id}/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
      "role": "user",
      "content": "Mình cần giải phương trình `3x + 11 = 14`. Bạn có thể giúp mình không?"
    }'

Các tham số API:

  • thread_id - đại diện cho ID luồng trò chuyện, mà bạn có thể thu được khi tạo Chủ Đề.

Thân yêu cầu API là một tin nhắn người dùng, thường đại diện cho câu hỏi của người dùng, tương tự cấu trúc tin nhắn của mô hình trò chuyện.

2.4 Chạy Trợ Lý để Tạo Ra Phản Hồi

Để trợ lý phản hồi tin nhắn của người dùng, bạn cần tạo một Run. Điều này cho phép trợ lý đọc Chủ Đề và quyết định liệu có sử dụng công cụ (nếu được kích hoạt) hay đơn giản chỉ sử dụng mô hình để trả lời yêu cầu tốt nhất.

Lưu ý: Đến điểm này, trợ lý chưa phản hồi câu hỏi của người dùng. Chỉ khi bạn gọi API Run thì trợ lý trí tuệ sẽ phản hồi câu hỏi của người dùng.

curl https://api.openai.com/v1/threads/{thread_id}/runs \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "assistant_id": "assistant_id",
    "instructions": "Address the user as Jane Doe. The user is a premium account."
  }'

Các tham số API:

  • thread_id - đại diện cho ID luồng trò chuyện, mà bạn có thể thu được khi tạo Chủ Đề.
  • assistant_id - đại diện cho ID trợ lý, mà bạn có thể thu được khi tạo Trợ Lý.
  • instructions - hướng dẫn của trợ lý có thể ghi đè lên các hướng dẫn được đặt khi tạo Trợ Lý.

Một yêu cầu API thành công sẽ trả về một ID Run.

2.5 Kiểm Tra Trạng Thái Chạy của Trợ Lý

Sau khi bắt đầu một nhiệm vụ (Run) trong Trợ Lý, việc thực hiện nhiệm vụ là không đồng bộ. Điều này có nghĩa là chúng ta cần kiểm tra định kỳ trạng thái của Run để xác định xem nó đã hoàn thành chưa. Để kiểm tra trạng thái của Run, có thể thực hiện một yêu cầu HTTP bằng CURL. Dưới đây là một sự giới thiệu cụ thể về quy trình này.

Ví dụ Yêu Cầu CURL:

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123 \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

Giải thích Tham Số API:

  • https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123: Đây là URL yêu cầu của API, trong đó thread_abc123 là định danh duy nhất của luồng (Thread), và run_abc123 là định danh duy nhất của Run.

Ví dụ Phản Hồi Yêu Cầu:

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "completed",
  "created_at": 1699073585,
  ...
}

Giải thích Tham Số Phản Hồi API:

  • id: Định danh duy nhất của Run.

  • object: Chỉ ra loại đối tượng được trả về, ở đây là thread.run.

  • status: Trạng thái của Run, các giá trị có thể là queued, in_progress, completed, requires_action, failed, v.v.

  • created_at: Thời điểm mà Run được tạo.

2.6 Nhận Kết Quả Phản Hồi từ Trợ Lý

Sau khi Trợ Lý kết thúc Run, chúng ta có thể đọc kết quả phản hồi của Trợ Lý bằng cách kiểm tra các tin nhắn được thêm vào luồng trò chuyện (Thread). Dưới đây là một minh họa về cách thực hiện yêu cầu thông qua CURL và một giải thích chi tiết về các tham số API.

Mẹo: Tương tự như việc trò chuyện với một Trợ Lý, khi Trợ Lý hoàn tất xử lý yêu cầu của người dùng, Trợ Lý sẽ thêm một tin nhắn vào luồng trò chuyện (Thread). Do đó, chúng ta chỉ cần truy vấn tin nhắn mới nhất trong luồng trò chuyện (Thread) để nhận phản hồi từ Trợ Lý.

Ví dụ Yêu Cầu CURL:

curl https://api.openai.com/v1/threads/thread_abc123/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

Giải thích Tham số API:

  • https://api.openai.com/v1/threads/thread_abc123/messages: URL yêu cầu của API, trong đó thread_abc123 là định danh duy nhất của luồng (Thread).
  • Tương tự như tiêu đề yêu cầu được sử dụng để kiểm tra trạng thái chạy trước đó, bao gồm thông tin xác thực và thông tin phiên bản API.

Kết quả Phản hồi của Trợ lí Ví dụ:

Trong ví dụ này, người dùng đã hỏi Trợ lí một câu hỏi toán học, và Trợ lí đã thêm một tin nhắn phản hồi vào Luồng sau khi xử lý nó.

Người dùng: Tôi cần giải phương trình `3x + 11 = 14`. Bạn có thể giúp tôi không?
Trợ lý: Tất nhiên, Jane Doe. Để giải phương trình `(3x + 11 = 14)`, bạn cần phải cô lập `(x)` ở một bên của phương trình. Hãy để tôi tính giá trị của `(x)` cho bạn.
Trợ lý: Giải phương trình `(3x + 11 = 14)` là `(x = 1)`.

Sau khi nhận được kết quả phản hồi từ Trợ lí, nó có thể được trình bày cho người dùng để giúp họ hiểu và sử dụng dịch vụ được cung cấp bởi Trợ lí.

3. Công cụ: Công cụ Tích hợp Sẵn của OpenAI

3.1 Công cụ Thực thi Mã

Công cụ Thực thi Mã cho phép API Trợ lý viết và chạy mã Python trong môi trường thực thi cát-sandbox. Công cụ này có thể xử lý các định dạng dữ liệu và tệp tin khác nhau, và tạo ra tệp tin chứa dữ liệu và hình ảnh đồ họa. Công cụ Thực thi Mã cho phép Trợ lý của bạn chạy mã một cách lặp để giải quyết các vấn đề lập trình và toán học phức tạp. Khi mã được viết bởi Trợ lí không chạy thành công, nó có thể chạy mã khác đến khi mã chạy thành công.

Kích hoạt Công cụ Thực thi Mã

Để kích hoạt Công cụ Thực thi Mã, truyền code_interpreter trong tham số tools khi tạo đối tượng Trợ lý:

curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "Bạn là gia sư toán học cá nhân. Khi được hỏi về một câu hỏi toán học, hãy viết và chạy mã để trả lời.",
    "tools": [
      { "type": "code_interpreter" }
    ],
    "model": "gpt-4-turbo-preview"
  }'

Sau đó, mô hình sẽ quyết định khi nào gọi Công cụ Thực thi Mã vào thời gian chạy dựa trên bản chất của yêu cầu của người dùng. Bạn có thể thuận tiện cho hành vi này thông qua instructions của Trợ lý (ví dụ: "Viết mã để giải quyết vấn đề này").

Sử dụng Công cụ Thực thi Mã để Xử lý Tệp

Công cụ Thực thi Mã có thể phân tích dữ liệu từ các tệp tin. Điều này hữu ích khi bạn muốn cung cấp một lượng lớn dữ liệu cho Trợ lý hoặc cho phép người dùng tải lên các tệp tin của họ để phân tích. Lưu ý rằng các tệp được tải lên cho Công cụ Thực thi Mã sẽ không được lập chỉ mục cho việc truy xuất. Đối với thông tin chi tiết về cách lập chỉ mục tệp cho việc truy xuất, xem phần Công cụ Truy xuất dưới đây.

Các tệp được truyền ở cấp độ Trợ lý có thể được truy cập bởi tất cả Các Chạy liên kết với Trợ lý này:

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/mydata.csv"

curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "Bạn là gia sư toán học cá nhân. Khi được hỏi về một câu hỏi toán học, hãy viết và chạy mã để trả lời.",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4-turbo-preview",
    "file_ids": ["file_123abc456"]
  }'

Đọc Hình Ảnh và Tệp Tin Được Tạo Bởi Trình Diễn Code

Trình Diễn Code cũng có thể đầu ra các tệp tin trong API, như tạo biểu đồ hình ảnh, tệp CSV, và tệp PDF. Có hai loại tệp tin được tạo ra: hình ảnh và tệp tin dữ liệu (ví dụ, tệp CSV chứa dữ liệu được tạo bởi Trợ Lý).

Khi Trình Diễn Code tạo ra một hình ảnh, bạn có thể tìm và tải tệp tin này trong trường file_id của phản hồi Tin Nhắn từ Trợ Lý:

{
    "id": "msg_abc123",
    "object": "thread.message",
    "created_at": 1698964262,
    "thread_id": "thread_abc123",
    "role": "assistant",
    "content": [
    {
      "type": "image_file",
      "image_file": {
        "file_id": "file-abc123"
      }
    }
  ]
  // ...
}

3.2 Công Cụ Trích Xuất

Công Cụ Trích Xuất nâng cao khả năng của Trợ Lý bằng cách thêm thông tin từ bên ngoài mô hình (như thông tin sản phẩm độc quyền hoặc tài liệu do người dùng cung cấp). Khi tệp tin được tải lên và chuyển đến Trợ Lý, OpenAI sẽ tự động cắt, lập chỉ mục, lưu trữ nhúng của tài liệu của bạn, và thực hiện tìm kiếm vector để truy xuất nội dung liên quan để trả lời câu hỏi của người dùng.

Kích Hoạt Trích Xuất

Để kích hoạt trích xuất trong tham số tools của Trợ Lý, hãy chuyển retrieval:

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "Bạn là một trò chuyện hỗ trợ khách hàng. Sử dụng cơ sở kiến thức của bạn để phản hồi hiệu quả các yêu cầu của khách hàng.",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview"
  }'

Tải Lên Tệp Tin cho Trích Xuất

Tương tự như Trình Diễn Code, tệp tin có thể được tải lên ở mức độ của Trợ Lý hoặc ở mức độ của từng Tin Nhắn cá nhân.

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/knowledge.pdf"

curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "Bạn là một trò chuyện hỗ trợ khách hàng. Sử dụng cơ sở kiến thức của bạn để phản hồi hiệu quả các yêu cầu của khách hàng.",
    "name": "Gia Sư Toán",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview"
    "file_ids": ["file_123abc456"]
  }'

3.3 Công Cụ Gọi Hàm

Tương tự như API Hoàn Thành Trò Chuyện, API Trợ Lý hỗ trợ gọi hàm. Gọi hàm cho phép bạn mô tả các hàm cho Trợ Lý và thông minh trả về hàm cần gọi cùng với các tham số của nó. Khi một cuộc gọi hàm được chạy, API Trợ Lý s

Định nghĩa Hàm

Khi tạo một Trợ lý, bạn có thể định nghĩa một bộ các hàm mà trợ lý có thể gọi. Các hàm này cần được chỉ định một cách rõ ràng khi tạo đối tượng trợ lý. Mỗi hàm nên có một tên duy nhất, mô tả và quy định tham số.

Đoạn mã dưới đây mô tả cách định nghĩa hai hàm bằng lệnh curl khi tạo một trợ lý:

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "Bạn là một bot dự báo thời tiết. Sử dụng các hàm được cung cấp để trả lời câu hỏi.",
    "tools": [{
      "type": "function",
      "function": {
        "name": "getCurrentWeather",
        "description": "Lấy thông tin thời tiết cho một địa điểm cụ thể",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "Thành phố và bang, ví dụ: San Francisco, CA"},
            "unit": {"type": "string", "enum": ["c", "f"]}
          },
          "required": ["location"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "getNickname",
        "description": "Lấy biệt danh cho một thành phố",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "Thành phố và bang, ví dụ: San Francisco, CA"}
          },
          "required": ["location"]
        }
      }
    }],
    "model": "gpt-4-turbo-preview"
  }'

Đọc các hàm gọi bởi Trợ lý

Khi người dùng gửi một tin nhắn tới trợ lý và nội dung của tin nhắn kích hoạt một cuộc gọi hàm, bạn cần đọc thông tin về cuộc gọi hàm này. Trong quá trình này, trợ lý sẽ tạo một chạy với trạng thái requires_action. Lúc này, bạn có thể truy xuất đối tượng Chạy để có thông tin chi tiết về cuộc gọi hàm.

Dưới đây là ví dụ về việc lấy đối tượng Chạy, cho thấy cách lấy thông tin về các cuộc gọi hàm:

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "requires_action",
  "required_action": {
    "type": "submit_tool_outputs",
    "submit_tool_outputs": {
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "getCurrentWeather",
            "arguments": "{\"location\":\"San Francisco\"}"
          }
        },
        {
          "id": "call_abc456",
          "type": "function",
          "function": {
            "name": "getNickname",
            "arguments": "{\"location\":\"Los Angeles\"}"
          }
        }
      ]
    }
  },
  ...
}

Tham số tool_calls chứa thông tin về cuộc gọi hàm, và bạn chỉ cần gọi hàm tương ứng trong chương trình cục bộ của bạn.

Gửi kết quả đầu ra của hàm

Sau khi thực thi cuộc gọi hàm cục bộ và có được kết quả, bạn cần gửi kết quả này đến trợ lý Assistants để trợ lý có thể tiếp tục xử lý yêu cầu của người dùng. Khi gửi kết quả đầu ra của hàm, bạn cần đảm bảo rằng kết quả được liên kết với cuộc gọi hàm ban đầu.

Dưới đây là mã ví dụ về cách gửi kết quả đầu ra của hàm:

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_123/submit_tool_outputs \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "tool_outputs": [
      {
        "tool_call_id": "call_abc123",
        "output": "{\"temperature\": \"22\", \"unit\": \"celsius\"}"
      }, 
      {
        "tool_call_id": "call_abc456",
        "output": "{\"nickname\": \"LA\"}"
      }
    ]
  }'

Giải thích tham số:

  • thread_abc123 đại diện cho ID của luồng cuộc trò chuyện
  • run_123 đại diện cho ID của đối tượng Chạy
  • tool_call_id đại diện cho ID của một cuộc gọi hàm cụ thể, được lấy từ tham số tool_calls trước đó.

Sau khi gửi thành công tất cả kết quả đầu ra của hàm, trạng thái của đối tượng Chạy sẽ được cập nhật lại, và trợ lý sẽ tiếp tục xử lý và trả về phản hồi cuối cùng cho người dùng.