+9

Hướng dẫn tạo chat bot với OpenAI Assistant bằng Python

Giới thiệu về OpenAI Assistant

Ngày 7/11/2023, OpenAI giới thiệu một loạt các dịch vụ mới trong đó có OpenAI Assistant hứa hẹn sẽ tạo sự bùng nổ mới trong việc viết các ứng dụng 'trợ giúp' người dùng trong những lĩnh vực chuyên biệt. Theo giải thích của OpenAI, Assistants API giúp các nhà phát triển dễ dàng tạo ra các trợ lý AI mạnh mẽ trong ứng dụng của họ. API này loại bỏ nhu cầu quản lý lịch sử trò chuyện và cung cấp quyền truy cập vào các công cụ do OpenAI có sẵn như Code Interpreter hay cho phép cả sử dụng các công cụ bên thứ 3 cung cấp thông qua cái gọi là Function Calling.

Khác biệt giữa Assistants API với OpenAI API trước đây? Rất rõ ràng qua đoạn giới thiệu trên, lịch sử trò truyện được lưu giữ (nghĩa là các câu hỏi, trả lời sẽ tự theo 1 luồng, giữ lại ngữ cảnh và các câu hỏi trả lời trước đó). Sử dụng các tool do OpenAPI cung cấp (ví dụ Code Interpreter) và cả các tool do bên thứ 3 cung cấp, quá là xịn xò! Hãy tưởng tượng bạn hỏi ChatGPT một câu hỏi về lập trình, phần code sẽ do Code Interpreter viết. Với Assistant API, bây giờ ứng dụng do chính bạn viết cũng có thể làm được điều đó!

Bài này sẽ hướng dẫn bạn sử dụng Assistants API tạo 1 chatbot đơn giản trên console có thể trả lời các câu hỏi về Toán cho người dùng.

Chuẩn bị

Python và thư viện OpenAI API

Bạn cần có Python, thư viện OpenAI API (cài bằng lệnh pip install openapi). Lưu ý nếu bạn đã cài thư viện OpenAPI trước đây thì cần nâng cấp lên bản mới nhất (lệnh pip install --upgrade openapi).

Tài khoản API

Bạn cũng cần có tài khoản của OpenAI API (lưu ý tài khoản này và tài khoản ChatGPT không phải là một nhé, tuy có thể chung 1 email đăng ký!) và nạp trước 1 khoản tiền vì khi sử dụng API bạn sẽ phải trả theo những gì mình dùng (số lượng request, có dùng tool hay không, v.v). Như trong ảnh, bạn vào phần Settings > Billing để nạp tiền bằng cách thêm Payment Methods, nhập thẻ tín dụng (OpenAI đã cho thanh toán bằng thẻ Việt Nam). Phí chi tiết các bạn có thể tham khảo trên trang của OpenAI, mình trong quá trình viết tutorial cũng như test sau khi xong có chạy khoảng vài chục lần mà mất chưa tới 1$. Đấy là ban đầu còn dùng tool Code Interpreter mặc dù không cần thiết (dùng tool lại phải trả thêm tiền)

Tạo API key

Sau đó bạn vào phần API keys để tạo 1 key mới. Key này sau khi tạo ra bạn nên lưu lại trong máy của mình.

Tạo chatbot

Kết nối tới OpenAI

Đầu tiên tạo 1 client kết nối tới OpenAI bằng API key tạo ở bước trước lưu ở trong file key.txt, sau đó tạo ra các đối tượng threads và assistants. Assistants đại diện cho một AI được xây dựng với mục đích cụ thể, sử dụng các mô hình của OpenAI, truy cập vào các tệp tin, duy trì các chuỗi thảo luận liên tục và sử dụng các công cụ khác nhau. Thread là một phiên trò chuyện giữa một Assistant và người dùng. Thread giúp đơn giản hóa việc phát triển ứng dụng bằng cách lưu trữ lịch sử tin nhắn và cắt bớt chúng khi cuộc trò chuyện trở nên quá dài so với khả năng xử lý của mô hình.

def get_openai_key():
  with open('key.txt') as f:
    return f.read().strip()
  
# Create a OpenAI connection to access its threads and assistants
openai_client = openai.OpenAI(api_key=get_openai_key())
openai_threads = openai_client.beta.threads
openai_assistants = openai_client.beta.assistants

Tạo Assistant

Để tạo Assistant, sử dụng hàm create và cung cấp các tham số như tên, lệnh, công cụ và mô hình. Nếu bạn biết về prompt engineering thì instructions chính là prompt mà ta nhúng sẵn vào để giúp trả lời câu hỏi của người dùng tốt hơn. Như trong ví dụ dưới đây, assistant trả về sẽ được gán là một gia sư môn Toán, nhờ đó khi người dùng hỏi các câu hỏi về Toán thì các câu trả lời sẽ sát với môn Toán hơn. Tham số tools xác định các tools mà assistant có thể dùng để trả lời, vì đây là 1 ví dụ đơn giản nên mình đang để rỗng. Tham số model xác định model mà assistant sẽ dùng để trả lời.

def create_assistant():
  assistant = openai_assistants.create(
    name="Math Tutor",
    instructions="You are a personal math tutor. You will help user to answer math questions.",
    tools=[],
    model="gpt-4-1106-preview"
  )
  print("[Math Tutor]: Hello there, I'm your personal math tutor. Do you need any help?")

  return assistant

Hỏi Assistant

Để hỏi asssistant một câu hỏi, ta sử dụng hàm create của threads.messages với các tham số sau:

  • thread_id: xác định luồng đang trao đổi hỏi đáp
  • role: vai trò, do user hỏi nên là user
  • content: là nội dung mà user muốn hỏi

Tiếp theo là tạo 1 'run' để assistant trả lời và đợi kết quả trả về từ 'run' đó. Khi tạo run mình lại có thể bổ sung thêm instructions (lại là prompting engineering). Như trong đoạn code dưới đây mình nhắc lại cho assistant là user không biết gì về Toán cả, trả lời chi tiết nhưng cũng phải đơn giản để hiểu.

def ask_assistant(user_question, thread, assistant):
  # Pass in the user question into the existing thread
  openai_threads.messages.create(
    thread_id=thread.id,
    role="user",
    content=user_question
  )
  # Use runs to wait for the assistant response 
  run = openai_threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions=f'Keep in mind that user has no knowledge of math, especially {user_question} so please explain the answer in detail and simple.'
  )
  
  is_running = True
  while is_running:
    run_status = openai_threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
    is_running = run_status.status != "completed"
    time.sleep(1)

  return run

Lấy câu trả lời từ assistant

Trong thread sẽ có nhiều messages (kết quả của những lần hỏi đáp), do vậy mình sẽ chỉ lấy messages cuối cùng và trích xuất nội dung của nó để hiển thị cho người dùng.

def assistant_response(thread, run):
  # Get the messages list from the thread
  messages = openai_threads.messages.list(thread_id=thread.id)
  # Get the last message for the current run
  last_message = [message for message in messages.data if message.run_id == run.id and message.role == "assistant"][-1]
  # If an assistant message is found, print it
  if last_message:
    print(f"[Math Tutor]: {last_message.content[0].text.value}")
  else:
    print(f"[Math Tutor]: I'm sorry, I am not sure how to answer that. Can you ask another question?")

Chương trình chính

Hàm main có logic đơn giản như sau:

  • Tạo 1 assistant
  • Tạo 1 thread để trao đổi
  • Lấy câu hỏi từ người dùng
  • Hỏi assistant
  • Nhận câu trả lời và hiển thị cho người dùng
def main():
  assistant = create_assistant()
  thread = openai_threads.create()

  asking = True
  user_question = ask_question()

  while asking:
    run = ask_assistant(user_question, thread, assistant)
    assistant_response(thread, run)
    user_question = ask_question()
    asking = user_question.lower() != "quit"

    if not asking:
      print("Goodbye! I hope you will do well on math.")

Code cho các bạn tham khảo: https://github.com/dttung79/openai_assistant

Kết quả chạy của chương trình Với 1 câu hỏi rất đơn giản, nhưng câu trả lời nhận được rất chi tiết. Đấy là do ta xác định tham số instructions khi hỏi (xem lại hàm ask_assistant). Nếu bỏ tham số instructions đi, câu trả lời sẽ rất đơn giản như hình dưới Nếu chưa thoả mãn, người dùng có thể yêu cầu giải thích và vì vẫn đang trong 1 luồng, assistant nắm được nội dung trước đó và nó sẽ giải thích vì sao 2+2=4

Kết luận

Ví dụ này mới minh hoạ một phần sức mạnh của Assistant API (tạo luồng hỏi đáp và chèn prompt để có câu trả lời tốt hơn). Ngoài ra còn có thể dùng tools do OpenAI cung cấp (hiện tại có Code Interpreter để viết code, và Retrieval để tải file lên, lưu file) hoặc do bên thứ 3 cung cấp. Sắp tới, chắc sẽ có rất nhiều ứng dụng được tạo ra cùng với Assistant API này.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí