Chuyển đến nội dung chính

API O4-Mini: Hướng dẫn từng bước kèm dự án demo

Tìm hiểu cách sử dụng API o4-mini của OpenAI để xây dựng trình phản biện bài báo khoa học, kết hợp công cụ thống kê cho phân tích chuyên sâu.
Đã cập nhật 5 thg 10, 2026  · 12 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

o4-mini của OpenAI là bổ sung mới nhất cho dòng mô hình AI tập trung vào suy luận o-series. Trong hướng dẫn này, tôi sẽ hướng dẫn bạn cách xây dựng một trình phản biện bài báo khoa học bằng cách sử dụng API o4-mini của OpenAI. Công cụ sẽ:

  • Trích xuất nội dung từ bài báo khoa học (PDF).
  • Làm nổi bật các lập luận yếu, tuyên bố thiếu cơ sở hoặc phương pháp luận có lỗi.
  • Đề xuất cải thiện và đưa ra kết luận.

Chúng ta cũng sẽ tăng cường trợ lý phản biện bằng hỗ trợ công cụ thống kê, để mô hình có thể tính p-value, kích thước hiệu ứng và khoảng tin cậy theo yêu cầu.

Chúng tôi luôn cập nhật cho độc giả về những điều mới nhất trong AI qua The Median, bản tin miễn phí phát hành thứ Sáu hằng tuần, tóm lược các câu chuyện quan trọng. Đăng ký để nắm bắt nhanh chỉ trong vài phút mỗi tuần:

Vì sao dùng O4-Mini?

o4-mini của OpenAI là mô hình suy luận hiệu năng cao, chi phí hợp lý, có khả năng phân tích sâu ở các tác vụ như lập trình, toán học và suy luận khoa học. Dù nhỏ hơn mô hình o3, nó vẫn liên tục đạt kết quả tiên tiến trên các benchmark như AIME 2024/2025 và GPQA.

Nhờ tốc độ và chi phí thấp, nó rất phù hợp cho các tác vụ như phản biện bài báo khoa học, tạo giải thích cho mã, hoặc hỗ trợ câu hỏi toán thi đấu. Các điểm mạnh chính gồm:

  • Hiệu năng toán và lập trình hàng đầu trong phân khúc kích thước của nó.
  • Độ trễ thấp, phù hợp cho khối lượng tác vụ lớn.
  • Bộ nhớ và chi phí hiệu quả, lý tưởng cho demo, thử nghiệm và công cụ nghiên cứu.

Để tìm hiểu thêm, hãy xem bài blog giới thiệu về o4-mini.

Tổng quan dự án: Trình phản biện bài báo với O4-Mini

Chúng ta sẽ xây dựng một trình phản biện bài báo khoa học dựa trên Python có thể:

  • Nhận bài báo do người dùng tải lên (PDF hoặc văn bản).
  • Trích xuất nội dung từ bài báo.
  • Dùng khả năng suy luận của o4-mini để phân tích lỗi logic hoặc lập luận yếu.
  • Hiển thị bài phản biện có cấu trúc gồm điểm yếu và gợi ý.

Dự án này chạy hoàn toàn cục bộ và sử dụng API của OpenAI.

Bước 1: Truy cập O4-Mini qua OpenAI API

Để dùng o4-mini, bạn cần khóa API từ OpenAI. Cách thực hiện:

  1. Truy cập https://platform.openai.com/account/api-keys
  2. Đăng nhập và bấm Create new secret key.
  3. Đặt tên (ví dụ: "o4-mini-key") và lưu an toàn.
  4. Nhớ nạp tiền vào tài khoản của bạn trong phần thanh toán.

Giờ bạn đã sẵn sàng xác thực và bắt đầu gọi API từ Python.

Bước 2: Cài đặt phụ thuộc

Bắt đầu bằng cách cài một vài phụ thuộc và thiết lập biến môi trường cho khóa API của chúng ta.

pip install openai PyMuPDF tiktoken numpy 
export OPENAI_API_KEY =” YOUR_KEY”

Bước 3: Mã hỗ trợ thống kê

Sau khi xong phụ thuộc, chuyển sang các hàm trợ giúp. Những hàm này sẽ được LLM gọi thông qua tool calls khi cần.

Bước 3.1: Import

Các import này dùng để tính kiểm định t, sai số chuẩn và khoảng tin cậy.

from scipy.stats import ttest_ind, sem, t
import numpy as np

Bước 3.2: Tính lại p-value

Hàm này thực hiện kiểm định t của Welch giữa hai nhóm mẫu độc lập. Nó kiểm định giả thuyết rằng trung bình của hai nhóm khác biệt có ý nghĩa thống kê.

def recalculate_p_value(group1, group2):
    t_stat, p_value = ttest_ind(group1, group2, equal_var=False)
    return {"p_value": round(p_value, 4)}

Hàm recalculate_p_value() trả về p-value, làm tròn đến bốn chữ số thập phân, biểu thị xác suất rằng khác biệt quan sát được xảy ra do ngẫu nhiên. Điều này giúp LLM kiểm chứng các tuyên bố về ý nghĩa thống kê trong bài báo.

Bước 3.3: Tính Cohen’s d

Cohen’s d là thước đo kích thước hiệu ứng chuẩn hóa giữa hai nhóm. Bắt đầu bằng việc tính trung bình và độ lệch chuẩn của mỗi nhóm. Sau đó dùng độ lệch chuẩn gộp để chuẩn hóa chênh lệch trung bình.

def compute_cohens_d(group1, group2):
    mean1, mean2 = np.mean(group1), np.mean(group2)
    std1, std2 = np.std(group1, ddof=1), np.std(group2, ddof=1)
    pooled_std = np.sqrt((std1**2 + std2**2) / 2)
    d = (mean1 - mean2) / pooled_std
    return {"cohens_d": round(d, 4)}

Hàm trả về giá trị Cohen’s d, làm tròn đến bốn chữ số thập phân. Điều này giúp LLM hiểu ý nghĩa thực tiễn (không chỉ thống kê) của khác biệt giữa các nhóm. Đặc biệt hữu ích khi cỡ mẫu lớn và p-value đơn thuần chưa đủ thông tin.

Bước 3.4: Tính khoảng tin cậy

Giờ ta định nghĩa hàm trợ giúp để tính khoảng tin cậy cho một nhóm mẫu. Khoảng tin cậy hữu ích để hiểu độ tin cậy của trung bình ước lượng — tức mức độ bất định quanh giá trị trung bình.

 
def compute_confidence_interval(data, confidence=0.95):
    data = np.array(data)
    n = len(data)
    mean = np.mean(data)
    margin = sem(data) * t.ppf((1 + confidence) / 2., n-1)
    return {
        "mean": round(mean, 4),
        "confidence_interval": [round(mean - margin, 4), round(mean + margin, 4)],
        "confidence": confidence
    }

Hàm này trả về:

  • mean: Giá trị trung bình của dữ liệu đầu vào.
  • confidence_interval: Danh sách biểu diễn cận dưới và cận trên trong đó trung bình thật có khả năng nằm, dựa trên mức tin cậy chỉ định.
  • confidence: Mức tin cậy dùng cho khoảng.

Bước 3.5: Thống kê nhóm

Kết thúc phần trợ giúp bằng một hàm đơn giản tóm tắt trung bình, độ lệch chuẩn và kích thước mẫu.

def describe_group(data):
    data = np.array(data)
    return {
        "mean": round(np.mean(data), 4),
        "std_dev": round(np.std(data, ddof=1), 4),
        "n": len(data)
    }

Điều này giúp LLM diễn giải phân phối dữ liệu nền, cung cấp ngữ cảnh thiết yếu để đánh giá kết quả. Bằng cách cung cấp các mô tả như trung bình, độ lệch chuẩn và số lượng, các công cụ trợ giúp của chúng ta tăng cường khả năng suy luận về thí nghiệm và tuyên bố trong bài báo.

Bước 4: Trình phản biện bài báo với hỗ trợ công cụ

Trong phần này, chúng ta sẽ xây dựng trình phản biện bài báo bằng Python sử dụng API o4-mini của OpenAI và bao gồm hỗ trợ công cụ phân tích thống kê, cho phép mô hình thực hiện đánh giá chặt chẽ và phản biện dựa trên dữ liệu.

Bước 4.1: Import

Chúng ta bắt đầu mã chính với một số thư viện thiết yếu để trích xuất nội dung PDF, tokenize và giao tiếp với OpenAI API.

import os
import fitz 
import openai
import json
import tiktoken
from statistics_helper import (
    recalculate_p_value,
    compute_cohens_d,
    compute_confidence_interval,
    describe_group
)
openai.api_key = os.getenv("OPENAI_API_KEY")

Giờ hãy xây dựng pipeline hoàn chỉnh từng bước.

Bước 4.2: Trích xuất văn bản từ PDF

Bắt đầu bằng cách đọc văn bản thô từ bài báo. Thư viện fitz cho phép lặp qua mọi trang và nối phần văn bản trích xuất thành một chuỗi.

def extract_text_from_pdf(path):
    doc = fitz.open(path)
    full_text = "\n".join(page.get_text() for page in doc)
    return full_text

Đây là nền tảng. Tiếp theo, chúng ta sẽ tokenize và chia khúc văn bản trước khi gửi tới mô hình.

Lưu ý: Tôi đã tạo một bài báo giả cho mục đích demo, cố ý chứa các lỗi logic và thiết kế thí nghiệm.

Bước 4.3: Chia khúc (Chunking)

LLM có giới hạn ngữ cảnh, nên ta chia tài liệu dài thành các khúc dễ xử lý. Chúng ta dùng Tiktoken để tokenize văn bản theo lược đồ mã hóa của mô hình.

def chunk_text(text, max_tokens=12000, model="o4-mini"):
    encoding = tiktoken.get_encoding("cl100k_base") 
    tokens = encoding.encode(text)
    chunks = []
    for i in range(0, len(tokens), max_tokens):
        chunk = tokens[i:i + max_tokens]
        chunk_text = encoding.decode(chunk)
        chunks.append(chunk_text)
    return chunks

Cách hoạt động:

  • Đầu tiên, dùng tiktoken để tokenize toàn bộ văn bản bằng cl100k_base tokenizer, tương thích với các mô hình OpenAI hiện đại như GPT-4, GPT-4o và o4-mini.
  • Văn bản đã tokenize được chia thành các đoạn có độ dài max_tokens. Điều này đảm bảo mỗi khúc nằm trong kích thước đầu vào tối đa mà mô hình cho phép, tránh lỗi tràn token khi suy luận.
  • Sau đó, mỗi khúc token được giải mã lại thành văn bản dễ đọc bằng encoding.decode(). Việc này giữ nguyên cách diễn đạt và định dạng tự nhiên để mô hình nhận được ngữ cảnh mạch lạc trong quá trình xử lý.
  • Cuối cùng, tất cả các khúc đã giải mã được gom vào một danh sách và trả về. Các khúc này sẵn sàng được gửi lần lượt tới LLM để phản biện, phân tích hoặc tạo nội dung.

Bước chia khúc này rất quan trọng để ngăn lỗi cắt cụt trong quá trình suy luận và đảm bảo không bỏ sót văn bản quan trọng do tràn.

Bước 4.4: Ánh xạ công cụ

Trước khi mô hình có thể gọi bất kỳ hàm bên ngoài nào, ta cần định nghĩa ánh xạ giữa tên hàm (mà mô hình nhìn thấy) và các hàm Python thực sự sẽ được thực thi. Ánh xạ này đóng vai trò cầu nối giữa tool calls của mô hình và mã cục bộ của chúng ta.

tool_function_map = {
    "recalculate_p_value": recalculate_p_value,
    "compute_cohens_d": compute_cohens_d,
    "compute_confidence_interval": compute_confidence_interval,
    "describe_group": describe_group,
}

Mỗi khóa trong từ điển này tương ứng với tên hàm mà mô hình có thể tham chiếu trong quá trình gọi công cụ, và mỗi giá trị là hàm Python thực tế được import từ mô-đun statistics_helper.

Bước 4.5: Định nghĩa công cụ

Để tăng cường suy luận của mô hình, chúng ta đăng ký các công cụ mà LLM có thể gọi qua function calling. Các công cụ này xử lý phân tích thống kê như tính lại p-value, khoảng tin cậy và kích thước hiệu ứng.

tools = [
            {
                "type": "function",
                "name": "recalculate_p_value",
                "description": "Calculate p-value between two sample groups",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "group1": {"type": "array", "items": {"type": "number"}},
                        "group2": {"type": "array", "items": {"type": "number"}}
                    },
                    "required": ["group1", "group2"]
                }
            },
            {
                "type": "function",
                "name": "compute_cohens_d",
                "description": "Compute effect size (Cohen's d) between two groups",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "group1": {"type": "array", "items": {"type": "number"}},
                        "group2": {"type": "array", "items": {"type": "number"}}
                    },
                    "required": ["group1", "group2"]
                }
            },
            {
                "type": "function",
                "name": "compute_confidence_interval",
                "description": "Compute confidence interval for a sample group",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "data": {"type": "array", "items": {"type": "number"}},
                        "confidence": {"type": "number", "default": 0.95}
                    },
                    "required": ["data"]
                }
            },
            {
                "type": "function",
                "name": "describe_group",
                "description": "Summarize sample mean, std deviation, and count",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "data": {"type": "array", "items": {"type": "number"}}
                    },
                    "required": ["data"]
                }
            }
        ]

Định nghĩa công cụ trên giúp LLM hiểu:

  • Công cụ làm gì (description)
  • Cách gọi công cụ (name)
  • Đầu vào mong đợi, gồm trường bắt buộc và kiểu dữ liệu (mảng số trong trường hợp này)

LLM sẽ tự quyết định khi nào cần gọi công cụ, ví dụ khi cần tính lại p-value, dựa trên ngữ cảnh phản biện. Khi gặp tuyên bố thống kê hoặc kết quả đáng ngờ, nó có thể gọi hàm trợ giúp phù hợp, nhận đầu ra, rồi tiếp tục suy luận dựa trên kết quả đó. Điều này cho phép phân tích chặt chẽ và có cơ sở hơn, nơi mô hình không chỉ phê bình mà còn kiểm chứng dữ liệu nền.

Bước 4.6: Phản biện từng khúc

Giờ chúng ta định nghĩa logic cốt lõi gửi mỗi khúc văn bản tới mô hình o4-mini. Nếu mô hình gọi công cụ, ta xử lý lệnh gọi hàm và tiếp tục hội thoại.

def review_text_chunk(chunk):
    try:
        response = client.responses.create(
            model="o4-mini",
            reasoning={"effort": "high"},
            input=[
                {
                    "role": "system",
                    "content": (
                        "You are an expert AI research reviewer. Read the given chunk of a research paper and highlight weak arguments."
                        "unsupported claims, or flawed methodology. You can request tools to: Recalculate p-values, Compute confidence intervals, "
                        "Estimate effect size (Cohen's d), Describe sample statistics. Be rigorous and explain your reasoning. "
                        "Conclude with suggestions and a verdict."
                    )
                },
                {
                    "role": "user",
                    "content": chunk
                }
            ],
            tools = tools,
        )
        # Check for tool calls
        for item in response.output:
            if getattr(item, "type", None) == "function_call":
                fn_call = getattr(item, "function_call", {})
                fn_name = getattr(fn_call, "name", "")
                args = getattr(fn_call, "arguments", {})
                if fn_name in tool_function_map:
                    tool_result = tool_function_map[fn_name](**args)
                    # Send back tool result as continuation input
                    tool_response = client.responses.create(
                        model="o4-mini",
                        reasoning={"effort": "high"},
                        input=[
                            *response.output,
                            {
                                "role": "tool",
                                "name": fn_name,
                                "content": str(tool_result)
                            }
                        ],
                        max_output_tokens=3000
                    )
                    if hasattr(tool_response, "output_text") and tool_response.output_text:
                        return tool_response.output_text.strip()
        # If no tool was called, return original response
        if hasattr(response, "output_text") and response.output_text:
            return response.output_text.strip()
        if response.status == "incomplete":
            reason = getattr(response.incomplete_details, "reason", "unknown")
            return f" Incomplete response: {reason}"
        return " No valid output returned by the model."
    except Exception as e:
        return f" Error during chunk review: {e}"

Hàm review_text_chunk chịu trách nhiệm gửi mỗi khúc bài báo tới LLM, kèm system prompt và danh mục công cụ. Cách hoạt động từng bước:

  1. Định nghĩa system prompt: System prompt yêu cầu mô hình hành xử như một chuyên gia phản biện bài báo AI. Nó yêu cầu mô hình:
    • Phân tích phần văn bản để tìm lỗi logic, tuyên bố thiếu cơ sở và vấn đề phương pháp.
    • Đồng thời gợi ý mô hình dùng các công cụ đã định nghĩa ở phần trước. Prompt này xác lập vai trò và định hướng mô hình đi vào chiều sâu phân tích.
  1. Lần gọi mô hình suy luận ban đầu: Khúc văn bản và system prompt được gửi tới mô hình bằng hàm client.responses.create() sử dụng Responses API cho suy luận. Trong lần gọi này:
    • Mô hình đặt là "o4-mini" và cờ reasoning={"effort": "high"} được đặt ở mức cao, khuyến khích suy luận nội bộ nhiều bước chi tiết. Thiết lập này cho biết mức độ mô hình nên “suy nghĩ” trước khi tạo câu trả lời cuối cùng, điều chỉnh số token suy luận nội bộ được phép dùng.
    • Tham số tools truyền danh sách các công cụ hàm có thể gọi.
    • Không cần đặt rõ tool_choice="auto" vì Responses API tự quyết định việc dùng công cụ.
  1. Xử lý việc dùng công cụ: Nếu mô hình quyết định gọi công cụ, chúng ta:
    • Trích xuất tên hàm và đối số từ lệnh gọi công cụ bằng cách kiểm tra đối tượng phản hồi có cấu trúc.
    • Gọi hàm Python cục bộ tương ứng với các đối số đó.
    • Cuối cùng, gửi đầu ra của công cụ trở lại mô hình bằng lần gọi thứ hai tới phương thức responses.create, bổ sung kết quả công cụ như một thông điệp vai trò "tool". Điều này mô phỏng việc tiếp nối quá trình suy luận.
  1. Diễn giải kết quả: Nếu có gọi công cụ, mô hình dùng kết quả trả về để tinh chỉnh phân tích và đưa ra phản biện nhiều dữ liệu hơn. Nếu không cần công cụ, nó trả kết luận trực tiếp từ lần gọi đầu.

Cơ chế suy luận và kiểm chứng nhiều bước này mang lại khả năng phản biện chặt chẽ cho mô hình. Nó mô phỏng cách một người phản biện sẽ phát hiện vấn đề, tính nhanh vài số liệu rồi điều chỉnh phản hồi tương ứng

Bước 4.7: Phản biện toàn bộ bài

Khi mọi thành phần đã sẵn sàng, chúng ta dùng hàm này để xử lý toàn bộ PDF. Nó liên kết tất cả lại với nhau.

def review_full_pdf(pdf_path):
    raw_text = extract_text_from_pdf(pdf_path)
    chunks = chunk_text(raw_text)
    print(f"\n Extracted {len(chunks)} chunks from PDF\n")
    all_reviews = []
    for idx, chunk in enumerate(chunks):
        print(f"\n  Reviewing Chunk {idx + 1}/{len(chunks)}...")
        review = review_text_chunk(chunk)
        all_reviews.append(f"### Chunk {idx + 1} Review\n{review}")
    full_review = "\n\n".join(all_reviews)
    return full_review

Hàm này đóng vai trò bao bọc để phản biện toàn bộ bài báo:

  • Đầu tiên trích xuất và chia khúc nội dung.
  • Sau đó gửi tuần tự từng khúc qua quy trình phản biện.
  • Cuối cùng tổng hợp mọi đầu ra thành một báo cáo duy nhất.

Bước 4.8: Hàm main

Giờ ta định nghĩa điểm vào của script. Điều này cho phép chạy chương trình trực tiếp từ terminal với đường dẫn file PDF làm đầu vào.

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Review an academic paper PDF for weak arguments.")
    parser.add_argument("pdf_path", type=str, help="Path to the research paper PDF")
    args = parser.parse_args()
    review_output = review_full_pdf(args.pdf_path)
    print("\n Final Aggregated Review:\n")
    print(review_output)
    with open("paper_review_output.md", "w") as f:
        f.write(review_output)
    print("\n Review saved to paper_review_output.md")

Khối này thực hiện:

  • Dùng argparse để nhận đường dẫn đến PDF như một tham số dòng lệnh.
  • Gọi hàm review_full_pdf() để tạo bài phản biện đầy đủ.
  • In kết quả cuối ra console.
  • Cuối cùng lưu bài phản biện ở định dạng Markdown (paper_review_output.md) để dùng sau hoặc tích hợp.

Để chạy mã này, gõ lệnh sau trong terminal:

python pdf_reviewer_assistant.py Fake_paper.pdf

Kết quả phản biện bài báo bằng o4-mini

Kết quả phản biện bài báo bằng o4-mini

Kết luận

Trong dự án này, chúng ta đã tạo một trình phản biện bài báo khoa học bằng API mô hình o4-mini của OpenAI. Chúng ta đã tăng cường khả năng của mô hình bằng cách tích hợp các công cụ thống kê thời gian thực, cho phép phân tích lại p-value, khoảng tin cậy và kích thước hiệu ứng.

Bản demo này mở đường cho các tích hợp sau này với giao diện PDF, công cụ kiểm tra trích dẫn, hoặc thậm chí trợ lý nghiên cứu đa phương thức.

Để tìm hiểu thêm về các bản phát hành gần đây của OpenAI, hãy xem các blog này:


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

Tôi là Chuyên gia Google Developers trong lĩnh vực ML (Gen AI), Chuyên gia Kaggle 3x và Đại sứ Women Techmakers với hơn 3 năm kinh nghiệm trong ngành công nghệ. Tôi đồng sáng lập một startup công nghệ y tế vào năm 2020 và hiện đang theo học thạc sĩ khoa học máy tính tại Georgia Tech, chuyên sâu về học máy.

Chủ đề
Trí tuệ Nhân tạo
Mô hình Ngôn ngữ Lớn
OpenAI

Học AI với các khóa học này!

Lộ trình

Phát triển các ứng dụng trí tuệ nhân tạo

21 giờ
Học cách phát triển các ứng dụng được hỗ trợ bởi trí tuệ nhân tạo (AI) bằng cách sử dụng các công cụ phát triển AI mới nhất, bao gồm API OpenAI, Hugging Face và LangChain.
Xem chi tiếtRight Arrow
Bắt Đầu Khóa Học
Xem thêmRight Arrow
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm