Tiếng Việt

Sử dụng Codex với Agents SDK

Gọi Codex dưới dạng máy chủ MCP để xây dựng quy trình phát triển đa tác nhân

Chạy Codex dưới dạng máy chủ MCP

Bạn có thể chạy Codex dưới dạng máy chủ MCP và kết nối máy chủ này từ các máy khách MCP khác (ví dụ: một tác nhân được xây dựng bằng tích hợp MCP của OpenAI Agents SDK).

Để khởi động Codex dưới dạng máy chủ MCP, bạn có thể dùng lệnh sau:

codex mcp-server

Bạn có thể khởi chạy máy chủ Codex MCP bằng Model Context Protocol Inspector:

npx @modelcontextprotocol/inspector codex mcp-server

Gửi một yêu cầu tools/list để xem hai công cụ:

codex: Chạy một phiên Codex với lời nhắc và các giá trị ghi đè cấu hình sau:

Thuộc tính Kiểu Mô tả
prompt (bắt buộc) string Lời nhắc ban đầu của người dùng để bắt đầu cuộc hội thoại Codex.
approval-policy string Chính sách phê duyệt cho các lệnh shell do mô hình tạo: untrusted, on-requestnever.
base-instructions string Tập hợp hướng dẫn dùng thay cho hướng dẫn mặc định.
compact-prompt string Lời nhắc dùng khi thu gọn cuộc hội thoại.
config object Các thiết lập cấu hình riêng lẻ ghi đè nội dung trong $CODEX_HOME/config.toml.
cwd string Thư mục làm việc của phiên. Nếu là đường dẫn tương đối, đường dẫn sẽ được phân giải theo thư mục hiện tại của tiến trình máy chủ.
developer-instructions string Hướng dẫn dành cho nhà phát triển được chèn dưới dạng thông điệp vai trò nhà phát triển.
model string Giá trị ghi đè không bắt buộc cho tên mô hình (ví dụ: gpt-5.6-terra).
sandbox string Chế độ sandbox: read-only, workspace-write hoặc danger-full-access.

codex-reply: Tiếp tục một phiên Codex bằng cách cung cấp ID luồng và lời nhắc. Công cụ codex-reply nhận các thuộc tính sau:

Thuộc tính Kiểu Mô tả
prompt (bắt buộc) string Lời nhắc tiếp theo của người dùng để tiếp tục cuộc hội thoại Codex.
threadId (bắt buộc) string ID của luồng cần tiếp tục.
conversationId (không còn được khuyến nghị) string Bí danh không còn được khuyến nghị của threadId (được giữ lại để đảm bảo khả năng tương thích).

Dùng threadId từ structuredContent.threadId trong phản hồi tools/call. Các lời nhắc phê duyệt (exec/patch) cũng chứa threadId trong tải trọng params của chúng.

Ví dụ về tải trọng phản hồi:

{
  "structuredContent": {
    "threadId": "019bbb20-bff6-7130-83aa-bf45ab33250e",
    "content": "`ls -lah` (or `ls -alh`) — long listing, includes dotfiles, human-readable sizes."
  },
  "content": [
    {
      "type": "text",
      "text": "`ls -lah` (or `ls -alh`) — long listing, includes dotfiles, human-readable sizes."
    }
  ]
}

Lưu ý rằng các máy khách MCP hiện đại thường chỉ báo cáo "structuredContent" làm kết quả của một lần gọi công cụ nếu trường này tồn tại, mặc dù máy chủ Codex MCP cũng trả về "content" để hỗ trợ các máy khách MCP cũ hơn.

Tạo quy trình đa tác nhân

Codex CLI có thể làm được nhiều hơn hẳn việc chạy các tác vụ đột xuất. Bằng cách cung cấp CLI dưới dạng máy chủ Model Context Protocol (MCP) và điều phối máy chủ đó bằng OpenAI Agents SDK, bạn có thể tạo các quy trình có tính xác định, dễ rà soát và có thể mở rộng từ một tác nhân duy nhất thành một quy trình phân phối phần mềm hoàn chỉnh.

Hướng dẫn này trình bày quy trình tương tự như trong OpenAI Cookbook. Bạn sẽ:

  • khởi chạy Codex CLI dưới dạng máy chủ MCP chạy dài hạn,
  • xây dựng một quy trình một tác nhân có trọng tâm để tạo ra trò chơi chạy được trên trình duyệt, và
  • điều phối một nhóm đa tác nhân với các bước bàn giao, rào chắn và toàn bộ dấu vết để bạn có thể xem lại sau đó.

Trước khi bắt đầu, hãy bảo đảm bạn có:

  • Codex CLI được cài đặt cục bộ để có thể dùng lệnh codex.
  • Python 3.10+ cùng với pip.
  • Node.js 18+ nếu bạn muốn chạy ví dụ MCP Inspector ở trên.
  • Một API key OpenAI được lưu cục bộ. Bạn có thể tạo hoặc quản lý khóa trong bảng điều khiển OpenAI.

Tạo một thư mục làm việc cho hướng dẫn và thêm API key của bạn vào tệp .env:

mkdir codex-workflows
cd codex-workflows
printf "OPENAI_API_KEY=sk-..." > .env

Cài đặt phần phụ thuộc

Agents SDK xử lý việc điều phối giữa Codex, các bước bàn giao và dấu vết. Cài đặt các gói SDK mới nhất:

python -m venv .venv
source .venv/bin/activate
pip install --upgrade openai openai-agents python-dotenv

Khởi tạo Codex CLI dưới dạng máy chủ MCP

Trước tiên, hãy chuyển Codex CLI thành một máy chủ MCP mà Agents SDK có thể gọi. Máy chủ cung cấp hai công cụ (codex() để bắt đầu cuộc hội thoại và codex-reply() để tiếp tục) và duy trì Codex hoạt động qua nhiều lượt của tác nhân.

Tạo một tệp có tên codex_mcp.py và thêm nội dung sau:

import asyncio

from agents import Agent, Runner
from agents.mcp import MCPServerStdio


async def main() -> None:
    async with MCPServerStdio(
        name="Codex CLI",
        params={
            "command": "codex",
            "args": ["mcp-server"],
        },
        client_session_timeout_seconds=360000,
    ) as codex_mcp_server:
        print("Codex MCP server started.")
        # More logic coming in the next sections.
        return


if __name__ == "__main__":
    asyncio.run(main())

Chạy tập lệnh một lần để xác minh Codex khởi chạy thành công:

python codex_mcp.py

Tập lệnh thoát sau khi in Codex MCP server started.. Trong các phần tiếp theo, bạn sẽ tái sử dụng cùng máy chủ MCP này trong những quy trình phong phú hơn.

Xây dựng quy trình một tác nhân

Hãy bắt đầu với một ví dụ có phạm vi rõ ràng, sử dụng Codex MCP để tạo một trò chơi nhỏ trên trình duyệt. Quy trình dựa vào hai tác nhân:

  1. Nhà thiết kế trò chơi: viết bản mô tả ngắn cho trò chơi.
  2. Nhà phát triển trò chơi: triển khai trò chơi bằng cách gọi Codex MCP.

Cập nhật codex_mcp.py bằng mã sau. Mã này giữ nguyên thiết lập máy chủ MCP ở trên và thêm cả hai tác nhân.

import asyncio
import os

from dotenv import load_dotenv

from agents import Agent, Runner, set_default_openai_api
from agents.mcp import MCPServerStdio

load_dotenv(override=True)
set_default_openai_api(os.getenv("OPENAI_API_KEY"))


async def main() -> None:
    async with MCPServerStdio(
        name="Codex CLI",
        params={
            "command": "codex",
            "args": ["mcp-server"],
        },
        client_session_timeout_seconds=360000,
    ) as codex_mcp_server:
        developer_agent = Agent(
            name="Game Developer",
            instructions=(
                "You are an expert in building simple games using basic html + css + javascript with no dependencies. "
                "Save your work in a file called index.html in the current directory. "
                "Always call codex with \"approval-policy\": \"never\" and \"sandbox\": \"workspace-write\"."
            ),
            mcp_servers=[codex_mcp_server],
        )

        designer_agent = Agent(
            name="Game Designer",
            instructions=(
                "You are an indie game connoisseur. Come up with an idea for a single page html + css + javascript game that a developer could build in about 50 lines of code. "
                "Format your request as a 3 sentence design brief for a game developer and call the Game Developer coder with your idea."
            ),
            model="gpt-5",
            handoffs=[developer_agent],
        )

        await Runner.run(designer_agent, "Implement a fun new game!")


if __name__ == "__main__":
    asyncio.run(main())

Thực thi tập lệnh:

python codex_mcp.py

Codex sẽ đọc bản mô tả của nhà thiết kế, tạo tệp index.html và ghi toàn bộ trò chơi vào đĩa. Mở tệp đã tạo trong trình duyệt để chơi. Mỗi lần chạy sẽ tạo ra một thiết kế khác nhau với những biến tấu độc đáo về lối chơi và mức độ hoàn thiện.

Mở rộng thành quy trình đa tác nhân

Bây giờ, hãy chuyển thiết lập một tác nhân thành một quy trình được điều phối và có thể theo dõi. Hệ thống bổ sung:

  • Quản lý dự án: tạo các yêu cầu dùng chung, điều phối việc bàn giao và thực thi các rào chắn.
  • Nhà thiết kế, Nhà phát triển frontend, Nhà phát triển máy chủNgười kiểm thử: mỗi tác nhân có hướng dẫn và thư mục đầu ra theo phạm vi riêng.

Tạo một tệp mới có tên multi_agent_workflow.py:

import asyncio
import os

from dotenv import load_dotenv

from agents import (
    Agent,
    ModelSettings,
    Runner,
    WebSearchTool,
    set_default_openai_api,
)
from agents.extensions.handoff_prompt import RECOMMENDED_PROMPT_PREFIX
from agents.mcp import MCPServerStdio
from openai.types.shared import Reasoning

load_dotenv(override=True)
set_default_openai_api(os.getenv("OPENAI_API_KEY"))


async def main() -> None:
    async with MCPServerStdio(
        name="Codex CLI",
        params={"command": "codex", "args": ["mcp-server"]},
        client_session_timeout_seconds=360000,
    ) as codex_mcp_server:
        designer_agent = Agent(
            name="Designer",
            instructions=(
                f"""{RECOMMENDED_PROMPT_PREFIX}"""
                "You are the Designer.\n"
                "Your only source of truth is AGENT_TASKS.md and REQUIREMENTS.md from the Project Manager.\n"
                "Do not assume anything that is not written there.\n\n"
                "You may use the internet for additional guidance or research."
                "Deliverables (write to /design):\n"
                "- design_spec.md – a single page describing the UI/UX layout, main screens, and key visual notes as requested in AGENT_TASKS.md.\n"
                "- wireframe.md – a simple text or ASCII wireframe if specified.\n\n"
                "Keep the output short and implementation-friendly.\n"
                "When complete, handoff to the Project Manager with transfer_to_project_manager."
                "When creating files, call Codex MCP with {\"approval-policy\":\"never\",\"sandbox\":\"workspace-write\"}."
            ),
            model="gpt-5",
            tools=[WebSearchTool()],
            mcp_servers=[codex_mcp_server],
        )

        frontend_developer_agent = Agent(
            name="Frontend Developer",
            instructions=(
                f"""{RECOMMENDED_PROMPT_PREFIX}"""
                "You are the Frontend Developer.\n"
                "Read AGENT_TASKS.md and design_spec.md. Implement exactly what is described there.\n\n"
                "Deliverables (write to /frontend):\n"
                "- index.html – main page structure\n"
                "- styles.css or inline styles if specified\n"
                "- main.js or game.js if specified\n\n"
                "Follow the Designer’s DOM structure and any integration points given by the Project Manager.\n"
                "Do not add features or branding beyond the provided documents.\n\n"
                "When complete, handoff to the Project Manager with transfer_to_project_manager_agent."
                "When creating files, call Codex MCP with {\"approval-policy\":\"never\",\"sandbox\":\"workspace-write\"}."
            ),
            model="gpt-5",
            mcp_servers=[codex_mcp_server],
        )

        backend_developer_agent = Agent(
            name="Backend Developer",
            instructions=(
                f"""{RECOMMENDED_PROMPT_PREFIX}"""
                "You are the Backend Developer.\n"
                "Read AGENT_TASKS.md and REQUIREMENTS.md. Implement the backend endpoints described there.\n\n"
                "Deliverables (write to /backend):\n"
                "- package.json – include a start script if requested\n"
                "- server.js – implement the API endpoints and logic exactly as specified\n\n"
                "Keep the code as simple and readable as possible. No external database.\n\n"
                "When complete, handoff to the Project Manager with transfer_to_project_manager_agent."
                "When creating files, call Codex MCP with {\"approval-policy\":\"never\",\"sandbox\":\"workspace-write\"}."
            ),
            model="gpt-5",
            mcp_servers=[codex_mcp_server],
        )

        tester_agent = Agent(
            name="Tester",
            instructions=(
                f"""{RECOMMENDED_PROMPT_PREFIX}"""
                "You are the Tester.\n"
                "Read AGENT_TASKS.md and TEST.md. Verify that the outputs of the other roles meet the acceptance criteria.\n\n"
                "Deliverables (write to /tests):\n"
                "- TEST_PLAN.md – bullet list of manual checks or automated steps as requested\n"
                "- test.sh or a simple automated script if specified\n\n"
                "Keep it minimal and easy to run.\n\n"
                "When complete, handoff to the Project Manager with transfer_to_project_manager."
                "When creating files, call Codex MCP with {\"approval-policy\":\"never\",\"sandbox\":\"workspace-write\"}."
            ),
            model="gpt-5",
            mcp_servers=[codex_mcp_server],
        )

        project_manager_agent = Agent(
            name="Project Manager",
            instructions=(
                f"""{RECOMMENDED_PROMPT_PREFIX}"""
                """
                You are the Project Manager.

                Objective:
                Convert the input task list into three project-root files the team will execute against.

                Deliverables (write in project root):
                - REQUIREMENTS.md: concise summary of product goals, target users, key features, and constraints.
                - TEST.md: tasks with [Owner] tags (Designer, Frontend, Backend, Tester) and clear acceptance criteria.
                - AGENT_TASKS.md: one section per role containing:
                  - Project name
                  - Required deliverables (exact file names and purpose)
                  - Key technical notes and constraints

                Process:
                - Resolve ambiguities with minimal, reasonable assumptions. Be specific so each role can act without guessing.
                - Create files using Codex MCP with {"approval-policy":"never","sandbox":"workspace-write"}.
                - Do not create folders. Only create REQUIREMENTS.md, TEST.md, AGENT_TASKS.md.

                Handoffs (gated by required files):
                1) After the three files above are created, hand off to the Designer with transfer_to_designer_agent and include REQUIREMENTS.md and AGENT_TASKS.md.
                2) Wait for the Designer to produce /design/design_spec.md. Verify that file exists before proceeding.
                3) When design_spec.md exists, hand off in parallel to both:
                   - Frontend Developer with transfer_to_frontend_developer_agent (provide design_spec.md, REQUIREMENTS.md, AGENT_TASKS.md).
                   - Backend Developer with transfer_to_backend_developer_agent (provide REQUIREMENTS.md, AGENT_TASKS.md).
                4) Wait for Frontend to produce /frontend/index.html and Backend to produce /backend/server.js. Verify both files exist.
                5) When both exist, hand off to the Tester with transfer_to_tester_agent and provide all prior artifacts and outputs.
                6) Do not advance to the next handoff until the required files for that step are present. If something is missing, request the owning agent to supply it and re-check.

                PM Responsibilities:
                - Coordinate all roles, track file completion, and enforce the above gating checks.
                - Do NOT respond with status updates. Just handoff to the next agent until the project is complete.
                """
            ),
            model="gpt-5",
            model_settings=ModelSettings(
                reasoning=Reasoning(effort="medium"),
            ),
            handoffs=[designer_agent, frontend_developer_agent, backend_developer_agent, tester_agent],
            mcp_servers=[codex_mcp_server],
        )

        designer_agent.handoffs = [project_manager_agent]
        frontend_developer_agent.handoffs = [project_manager_agent]
        backend_developer_agent.handoffs = [project_manager_agent]
        tester_agent.handoffs = [project_manager_agent]

        task_list = """
Goal: Build a tiny browser game to showcase a multi-agent workflow.

High-level requirements:
- Single-screen game called "Bug Busters".
- Player clicks a moving bug to earn points.
- Game ends after 20 seconds and shows final score.
- Optional: submit score to a simple backend and display a top-10 leaderboard.

Roles:
- Designer: create a one-page UI/UX spec and basic wireframe.
- Frontend Developer: implement the page and game logic.
- Backend Developer: implement a minimal API (GET /health, GET/POST /scores).
- Tester: write a quick test plan and a simple script to verify core routes.

Constraints:
- No external database—memory storage is fine.
- Keep everything readable for beginners; no frameworks required.
- All outputs should be small files saved in clearly named folders.
"""

        result = await Runner.run(project_manager_agent, task_list, max_turns=30)
        print(result.final_output)


if __name__ == "__main__":
    asyncio.run(main())

Chạy tập lệnh và theo dõi các tệp được tạo:

python multi_agent_workflow.py
ls -R

Tác nhân quản lý dự án ghi REQUIREMENTS.md, TEST.mdAGENT_TASKS.md, sau đó điều phối việc bàn giao giữa các tác nhân thiết kế, frontend, máy chủ và kiểm thử. Mỗi tác nhân ghi các sản phẩm theo phạm vi vào thư mục riêng trước khi chuyển quyền điều khiển lại cho quản lý dự án.

Theo dõi quy trình

Codex tự động ghi lại dấu vết chứa mọi lời nhắc, lần gọi công cụ và bước bàn giao. Sau khi lượt chạy đa tác nhân hoàn tất, hãy mở bảng điều khiển Traces để kiểm tra dòng thời gian thực thi.

Dấu vết cấp cao cho thấy cách quản lý dự án xác minh các bước bàn giao trước khi tiếp tục. Nhấp vào từng bước để xem lời nhắc, các lần gọi Codex MCP, tệp đã ghi và thời lượng thực thi. Những chi tiết này giúp bạn dễ dàng kiểm tra mọi bước bàn giao và hiểu quy trình đã phát triển như thế nào qua từng lượt. Các dấu vết này giúp bạn dễ dàng gỡ lỗi các trục trặc trong quy trình, kiểm tra hành vi của tác nhân và đo lường hiệu năng theo thời gian mà không cần thêm công cụ đo lường.