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.