OpenAI Function Calling là gì?
OpenAI API rất hiệu quả trong việc tạo phản hồi theo cách có hệ thống. Bạn có thể quản lý prompt, tối ưu hóa đầu ra của mô hình, và xây dựng các ứng dụng ngôn ngữ chỉ với vài dòng mã.
Dù có nhiều ưu điểm, OpenAI API từng là cơn ác mộng với lập trình viên và kỹ sư. Vì sao? Họ quen làm việc với dữ liệu có cấu trúc, trong khi xử lý dữ liệu phi cấu trúc như chuỗi văn bản thì khó.
Để có kết quả nhất quán, nhà phát triển phải dùng biểu thức chính quy (RegEx) hoặc kỹ thuật prompt để trích xuất thông tin từ chuỗi văn bản.
Đây là lúc khả năng gọi hàm của OpenAI phát huy tác dụng. Nó cho phép các mô hình GPT-3.5 và GPT-4 nhận các hàm do người dùng định nghĩa làm đầu vào và tạo đầu ra có cấu trúc. Nhờ vậy, bạn không cần viết RegEx hay thực hiện kỹ thuật prompt.
Trong hướng dẫn này, tôi sẽ giải thích từng bước cách gọi hàm của OpenAI giúp giải quyết các vấn đề thường gặp của nhà phát triển do đầu ra không đồng đều gây ra.
Sử dụng OpenAI Không có Gọi Hàm
Trong phần này, chúng ta sẽ tạo phản hồi bằng mô hình GPT-3.5-Turbo mà không dùng gọi hàm để xem đầu ra có nhất quán hay không.
Trước khi cài đặt OpenAI Python API, bạn cần lấy khóa API và thiết lập trên hệ thống cục bộ. Hãy theo dõi hướng dẫn GPT-3.5 và GPT-4 qua OpenAI API trong Python để biết cách lấy và thiết lập khóa API. Hướng dẫn cũng bao gồm ví dụ thiết lập biến môi trường trong DataLab, sổ tay dữ liệu hỗ trợ AI của DataCamp.
Để được hỗ trợ thêm, hãy xem mã trong sổ tay OpenAI Function Calling trên DataLab.
Nâng cấp OpenAI Python API lên V1 bằng:
pip install --upgrade openai -q
Sau đó, khởi tạo client OpenAI bằng khóa API.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ['OPENAI_API_KEY'],
)
Lưu ý: OpenAI không còn cung cấp tín dụng miễn phí cho người dùng mới, vì vậy bạn cần mua để sử dụng API.
Chúng ta sẽ viết một mô tả ngẫu nhiên về sinh viên. Bạn có thể tự viết hoặc dùng ChatGPT để tạo.
student_1_description = "David Nguyen is a sophomore majoring in computer science at Stanford University. He is Asian American and has a 3.8 GPA. David is known for his programming skills and is an active member of the university's Robotics Club. He hopes to pursue a career in artificial intelligence after graduating."
Tiếp theo, chúng ta sẽ viết một prompt để trích xuất thông tin sinh viên từ văn bản và trả về đầu ra dạng đối tượng JSON. Ta sẽ trích xuất họ tên, chuyên ngành, trường, điểm số và câu lạc bộ trong phần mô tả sinh viên.
# A simple prompt to extract information from "student_description" in a JSON format.
prompt1 = f'''
Please extract the following information from the given text and return it as a JSON object:
name
major
school
grades
club
This is the body of text to extract the information from:
{student_1_description}
'''
Thêm prompt vào mô-đun chat completion của OpenAI API để tạo phản hồi.
# Generating response back from gpt-3.5-turbo
openai_response = client.chat.completions.create(
model = 'gpt-3.5-turbo',
messages = [{'role': 'user', 'content': prompt_1}]
)
openai_response.choices[0].message.content
Phản hồi khá tốt. Hãy chuyển nó sang JSON để dễ hiểu hơn.
'{\n "name": "David Nguyen",\n "major": "computer science",\n "school": "Stanford University",\n "grades": "3.8 GPA",\n "club": "Robotics Club"\n}'
Chúng ta sẽ dùng thư viện `json` để chuyển văn bản thành đối tượng JSON.
import json
# Loading the response as a JSON object
json_response = json.loads(openai_response.choices[0].message.content)
json_response
Kết quả cuối cùng gần như hoàn hảo. Vậy, tại sao cần Function Calling?
{'name': 'David Nguyen',
'major': 'computer science',
'school': 'Stanford University',
'grades': '3.8 GPA',
'club': 'Robotics Club'}
Hãy thử cùng prompt đó nhưng với mô tả sinh viên khác.
student_2_description="Ravi Patel is a sophomore majoring in computer science at the University of Michigan. He is South Asian Indian American and has a 3.7 GPA. Ravi is an active member of the university's Chess Club and the South Asian Student Association. He hopes to pursue a career in software engineering after graduating."
Chúng ta chỉ cần thay đổi văn bản mô tả sinh viên trong prompt.
prompt2 = f'''
Please extract the following information from the given text and return it as a JSON object:
name
major
school
grades
club
This is the body of text to extract the information from:
{student_2_description}
'''
Và chạy hàm chat completion với prompt thứ hai.
# Generating response back from gpt-3.5-turbo
openai_response = client.chat.completions.create(
model = 'gpt-3.5-turbo',
messages = [{'role': 'user', 'content': prompt_2}]
)
# Loading the response as a JSON object
json_response = json.loads(openai_response.choices[0].message.content)
json_response
Như bạn thấy, kết quả không nhất quán. Thay vì trả về một câu lạc bộ, nó trả về danh sách các câu lạc bộ mà Ravi tham gia. Điều này cũng khác với sinh viên đầu tiên.
{'name': 'Ravi Patel',
'major': 'computer science',
'school': 'University of Michigan',
'grades': '3.7 GPA',
'club': ['Chess Club', 'South Asian Student Association']}
Ví dụ về OpenAI Function Calling
Để giải quyết vấn đề này, chúng ta sẽ dùng tính năng mới ra mắt có tên Function Calling. Cần tạo một hàm tùy chỉnh để thêm thông tin cần thiết vào danh sách các dictionary để OpenAI API hiểu chức năng của nó.
- name: viết tên hàm Python bạn vừa tạo.
- description: mô tả chức năng của hàm.
- parameters: trong “properties”, chúng ta sẽ ghi tên đối số, kiểu dữ liệu và mô tả. Điều này giúp OpenAI API nhận diện đúng những trường mà chúng ta cần.
Lưu ý: Hãy đảm bảo bạn làm đúng mẫu. Tìm hiểu thêm về gọi hàm trong tài liệu chính thức.
student_custom_functions = [
{
'name': 'extract_student_info',
'description': 'Get the student information from the body of the input text',
'parameters': {
'type': 'object',
'properties': {
'name': {
'type': 'string',
'description': 'Name of the person'
},
'major': {
'type': 'string',
'description': 'Major subject.'
},
'school': {
'type': 'string',
'description': 'The university name.'
},
'grades': {
'type': 'integer',
'description': 'GPA of the student.'
},
'club': {
'type': 'string',
'description': 'School club for extracurricular activities. '
}
}
}
}
]
Tiếp theo, chúng ta sẽ tạo phản hồi cho hai mô tả sinh viên bằng cách thêm hàm tùy chỉnh vào đối số "functions". Sau đó, chúng ta sẽ chuyển phản hồi văn bản thành đối tượng JSON và in ra.
student_description = [student_1_description,student_2_description]
for i in student_description:
response = client.chat.completions.create(
model = 'gpt-3.5-turbo',
messages = [{'role': 'user', 'content': i}],
functions = student_custom_functions,
function_call = 'auto'
)
# Loading the response as a JSON object
json_response = json.loads(response.choices[0].message.function_call.arguments)
print(json_response)
Như ta thấy, chúng ta nhận được đầu ra đồng nhất. Thậm chí điểm số được trả về dạng số thay vì chuỗi. Đầu ra nhất quán là yếu tố then chốt để xây dựng ứng dụng AI ít lỗi.
{'name': 'David Nguyen', 'major': 'computer science', 'school': 'Stanford University', 'grades': 3.8, 'club': 'Robotics Club'}
{'name': 'Ravi Patel', 'major': 'computer science', 'school': 'University of Michigan', 'grades': 3.7, 'club': 'Chess Club'}
Nhiều Hàm Tùy Chỉnh
Bạn có thể thêm nhiều hàm tùy chỉnh vào hàm chat completion. Trong phần này, chúng ta sẽ xem khả năng đáng chú ý của OpenAI API và cách nó tự động chọn đúng hàm, trả về tham số phù hợp.
Trong danh sách Python gồm các dictionary, chúng ta sẽ thêm hàm khác tên “extract_school_info,” giúp trích xuất thông tin trường đại học từ văn bản.
Để làm được điều này, bạn cần thêm một dictionary khác mô tả hàm với name, description và parameters.
custom_functions = [
{
'name': 'extract_student_info',
'description': 'Get the student information from the body of the input text',
'parameters': {
'type': 'object',
'properties': {
'name': {
'type': 'string',
'description': 'Name of the person'
},
'major': {
'type': 'string',
'description': 'Major subject.'
},
'school': {
'type': 'string',
'description': 'The university name.'
},
'grades': {
'type': 'integer',
'description': 'GPA of the student.'
},
'club': {
'type': 'string',
'description': 'School club for extracurricular activities. '
}
}
}
},
{
'name': 'extract_school_info',
'description': 'Get the school information from the body of the input text',
'parameters': {
'type': 'object',
'properties': {
'name': {
'type': 'string',
'description': 'Name of the school.'
},
'ranking': {
'type': 'integer',
'description': 'QS world ranking of the school.'
},
'country': {
'type': 'string',
'description': 'Country of the school.'
},
'no_of_students': {
'type': 'integer',
'description': 'Number of students enrolled in the school.'
}
}
}
}
]
Chúng ta sẽ tạo mô tả về “Stanford University” bằng ChatGPT để kiểm thử hàm.
school_1_description = "Stanford University is a private research university located in Stanford, California, United States. It was founded in 1885 by Leland Stanford and his wife, Jane Stanford, in memory of their only child, Leland Stanford Jr. The university is ranked #5 in the world by QS World University Rankings. It has over 17,000 students, including about 7,600 undergraduates and 9,500 graduates23. "
Tạo danh sách mô tả sinh viên và trường, rồi truyền qua hàm chat completion của OpenAI để tạo phản hồi. Hãy chắc chắn bạn đã cung cấp bộ hàm tùy chỉnh đã cập nhật.
description = [student_1_description, school_1_description]
for i in description:
response = client.chat.completions.create(
model = 'gpt-3.5-turbo',
messages = [{'role': 'user', 'content': i}],
functions = custom_functions,
function_call = 'auto'
)
# Loading the response as a JSON object
json_response = json.loads(response.choices[0].message.function_call.arguments)
print(json_response)
Mô hình GPT-3.5-Turbo đã tự động chọn đúng hàm cho các loại mô tả khác nhau. Chúng ta nhận được JSON hoàn hảo cho cả sinh viên và trường học.
{'name': 'David Nguyen', 'major': 'computer science', 'school': 'Stanford University', 'grades': 3.8, 'club': 'Robotics Club'}
{'name': 'Stanford University', 'ranking': 5, 'country': 'United States', 'no_of_students': 17000}
Chúng ta thậm chí có thể xem ở dưới tên cho biết phản hồi được tạo bằng hàm “extract_school_info”.

Ứng dụng của Function Calling
Trong phần này, chúng ta sẽ xây dựng một bộ tóm tắt văn bản ổn định để tóm tắt thông tin trường và sinh viên theo một cách nhất định.
Trước hết, chúng ta sẽ tạo hai hàm Python, extract_student_info và extract_school_info, nhận tham số từ lời gọi hàm và trả về chuỗi tóm tắt.
def extract_student_info(name, major, school, grades, club):
"""Get the student information"""
return f"{name} is majoring in {major} at {school}. He has {grades} GPA and he is an active member of the university's {club}."
def extract_school_info(name, ranking, country, no_of_students):
"""Get the school information"""
return f"{name} is located in the {country}. The university is ranked #{ranking} in the world with {no_of_students} students."
- Tạo danh sách Python bao gồm mô tả sinh viên thứ nhất, một prompt ngẫu nhiên và mô tả trường thứ nhất. Prompt ngẫu nhiên được thêm vào để kiểm chứng cơ chế gọi hàm tự động.
- Chúng ta sẽ tạo phản hồi cho từng văn bản trong danh sách `descriptions`.
- Nếu có sử dụng lời gọi hàm, chúng ta sẽ lấy tên hàm và dựa vào đó áp dụng các tham số phù hợp cho hàm bằng phản hồi. Nếu không, trả về phản hồi văn bản thông thường.
- In kết quả của cả ba mẫu.
descriptions = [
student_1_description,
"Who was a Abraham Lincoln?",
school_1_description
]
for i, sample in enumerate(descriptions):
response = client.chat.completions.create(
model = 'gpt-3.5-turbo',
messages = [{'role': 'user', 'content': sample}],
functions = custom_functions,
function_call = 'auto'
)
response_message = response.choices[0].message
if dict(response_message).get('function_call'):
# Which function call was invoked
function_called = response_message.function_call.name
# Extracting the arguments
function_args = json.loads(response_message.function_call.arguments)
# Function names
available_functions = {
"extract_school_info": extract_school_info,
"extract_student_info": extract_student_info
}
fuction_to_call = available_functions[function_called]
response_message = fuction_to_call(*list(function_args .values()))
else:
response_message = response_message.content
print(f"\nSample#{i+1}\n")
print(response_message)
- Sample#1: Mô hình GPT đã chọn “extract_student_info,” và chúng ta nhận được phần tóm tắt ngắn về sinh viên.
- Sample#2: Mô hình GPT không chọn hàm nào và xem prompt như một câu hỏi thông thường, vì vậy chúng ta nhận được tiểu sử của Abraham Lincoln.
- Sample#3: Mô hình GPT đã chọn “extract_school_info,” và chúng ta có phần tóm tắt ngắn về Stanford University.
Sample#1
David Nguyen is majoring in computer science at Stanford University. He has 3.8 GPA and he is an active member of the university's Robotics Club.
Sample#2
Abraham Lincoln was the 16th President of the United States. He served as president from March 1861 until his assassination in April 1865. Lincoln led the country through its greatest internal crisis, the American Civil War, and his Emancipation Proclamation declared slaves in Confederate territory to be free. He is known for his leadership, his commitment to preserving the Union, and his efforts to abolish slavery. Lincoln's presidency is widely regarded as one of the most transformative in American history.
Sample#3
Stanford University is located in the United States. The university is ranked #5 in the world with 17000 students.
Kết luận
Trong hướng dẫn này, chúng ta đã tìm hiểu về gọi hàm của OpenAI. Chúng ta cũng học cách dùng nó để tạo đầu ra nhất quán, tạo nhiều hàm và xây dựng bộ tóm tắt văn bản đáng tin cậy.
Nếu bạn muốn tìm hiểu thêm về OpenAI API, hãy cân nhắc tham gia khóa học Làm việc với OpenAI API và sử dụng cheat sheet OpenAI API trong Python để tạo dự án AI đầu tiên của bạn.
Câu hỏi thường gặp
OpenAI function calling xử lý các đầu ra JSON lồng nhau phức tạp như thế nào?
OpenAI function calling cho phép bạn định nghĩa các cấu trúc JSON lồng nhau trong schema của hàm. Bằng cách chỉ định mối quan hệ phân cấp trong thuộc tính parameters, bạn có thể đảm bảo mô hình tạo ra các đầu ra JSON được lồng ghép và có cấu trúc đúng cho các yêu cầu dữ liệu phức tạp.
OpenAI function calling có thể dùng với API hoặc cơ sở dữ liệu bên ngoài không?
Có. OpenAI function calling có thể tích hợp với API hoặc cơ sở dữ liệu bên ngoài bằng cách tạo các hàm tùy chỉnh thực thi lời gọi API hoặc truy vấn cơ sở dữ liệu dựa trên các tham số được truyền từ mô hình. Điều này cho phép tương tác động với hệ thống bên ngoài đồng thời vẫn duy trì phản hồi có cấu trúc và nhất quán.
Điều gì xảy ra nếu lời gọi hàm của mô hình không khớp với hàm nào đã định nghĩa?
Nếu lời gọi hàm của mô hình không khớp với hàm đã định nghĩa hoặc schema cung cấp, lời gọi hàm sẽ không được kích hoạt và mô hình sẽ xử lý đầu vào như một prompt văn bản thông thường, trả về phản hồi dạng văn bản điển hình. Điều này đảm bảo tính linh hoạt khi xử lý các loại đầu vào khác nhau.
Là một nhà khoa học dữ liệu được chứng nhận, tôi đam mê tận dụng công nghệ tiên tiến để tạo ra các ứng dụng học máy đổi mới. Với nền tảng vững chắc về nhận dạng giọng nói, phân tích và báo cáo dữ liệu, MLOps, AI hội thoại và NLP, tôi đã rèn giũa kỹ năng phát triển các hệ thống thông minh có thể tạo ra tác động thực sự. Bên cạnh chuyên môn kỹ thuật, tôi cũng là một người truyền đạt tốt, có khả năng chắt lọc các khái niệm phức tạp thành ngôn ngữ rõ ràng, súc tích. Nhờ đó, tôi trở thành một blogger được nhiều người quan tâm trong lĩnh vực khoa học dữ liệu, chia sẻ góc nhìn và kinh nghiệm với cộng đồng các chuyên gia dữ liệu ngày càng lớn. Hiện tại, tôi tập trung vào sáng tạo và biên tập nội dung, làm việc với các mô hình ngôn ngữ lớn để phát triển nội dung mạnh mẽ và hấp dẫn, giúp doanh nghiệp và cá nhân tận dụng tối đa dữ liệu của mình.
