SynapseWire

OpenAI Agents SDK 實戰:用 Responses API 與 MCP 搭一個真正能工作的研究型 Agent

這篇教程帶你用 OpenAI Agents SDK、Responses API 與 Hosted MCP Tool 搭建研究型 AI Agent,重點放在工具選型、權限控制與可落地的工作流設計。

作者: SynapseWire 編輯部 發布於:
研究型 AI Agent 工作流介面,包含 Web Search、MCP 工具與審批節點

很多 Agent 教程都停在這一步:

agent = Agent(name="assistant", instructions="You are helpful")

程式確實能跑,但離「真的能用」還差很遠。研究型 Agent 最麻煩的地方不是把 Agent() 寫出來,而是三件事要同時處理好:拿到最新資訊、接上外部工具、別讓模型在不該動手的地方亂動。

這篇文章想解決的就是這個落差。我會用 OpenAI 官方文檔裡已經穩定的能力,把一個研究型工作流拆清楚:Agents SDK 負責編排,Responses API 負責模型與托管工具,MCP 則負責把外部能力接進來。這樣搭出來的系統,不只看起來像 Agent,實際上也比較接近團隊能長期維護的版本。

這篇會帶你學到什麼

  • 什麼時候該用 Agents SDK,什麼時候該直接用 Responses API
  • 如何先用 Web Search 打通「最新資訊」這一層
  • 如何用 Hosted MCP Tool 把遠端工具面接進 Agent
  • 如何把審批、權限和工具邊界放在一開始就想清楚

預計閱讀時間: 10 分鐘
難度: 中階

開始前,先把三層角色分清楚

如果你把 Agents SDK、Responses API 和 MCP 混成同一件事,後面一定會越寫越亂。比較好記的方式是這樣:

  • Responses API:負責模型回合、工具配置和托管能力,例如 Web Search、File Search、Hosted MCP。
  • Agents SDK:負責 Agent loop、handoff、guardrails、trace 和多步驟執行。
  • MCP:不是某一家的 SDK,而是一個協議。它用 JSON-RPC 把 host、client、server 之間的工具與上下文交換標準化。

MCP 官方規範把 server 能暴露的能力分成 toolsresourcesprompts。這個分類很重要,因為它提醒我們一件事:不是所有外部能力都該包成「可執行工具」。有些內容更適合當資源,有些流程更適合當提示模板。

準備環境

官方 Quickstart 的起手式很直接,先把虛擬環境和 SDK 裝起來:

python -m venv .venv
source .venv/bin/activate
pip install openai-agents openai
export OPENAI_API_KEY="sk-..."

如果你接下來要打遠端 MCP server,還要先準備兩樣東西:

  • 你信任的 MCP server URL
  • 如果服務需要授權,對應的 OAuth access token

這裡我刻意強調「信任」。OpenAI 在 MCP 指南裡寫得很直白,遠端 MCP server 可能接觸模型上下文中的敏感資料,所以不要把任何來路不明的 server 直接丟進 production。

步驟 1:先做一個能查最新資訊的研究 Agent

研究型工作流的第一層,不是資料庫,也不是 handoff,而是「能拿到今天的資訊」。如果這層沒打通,後面的外部工具就算接再多,也只是讓模型更快地在過時資訊上做決策。

Agents SDK 已經把 Web SearchTool 包好了,先從這個版本起步最合理:

import asyncio
from agents import Agent, Runner, WebSearchTool

research_agent = Agent(
    name="Research Agent",
    model="gpt-5.4",
    instructions=(
        "You are a research assistant. "
        "Use web search for current facts, cite sources clearly, "
        "and separate confirmed facts from open questions."
    ),
    tools=[WebSearchTool()],
)

async def main():
    result = await Runner.run(
        research_agent,
        "Summarize the latest MCP adoption patterns for developer tools.",
    )
    print(result.final_output)

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

這段程式的價值不只是「能搜尋」,而是它把研究工作流的責任切得很乾淨。模型知道自己可以查網頁,Responses API 也會在輸出裡帶上 citations 與 web_search_call 記錄。這對後續除錯很有幫助,因為你終於能看見模型到底查了什麼,而不是只收到一段像真的一樣的總結。

OpenAI 的 Web Search 文檔也提醒了一個常被忽略的細節:搜尋模式其實分成 deep research、帶推理的 agentic search 和非推理快速搜尋。做工作流設計時,這不是理論差異,而是成本和延遲差異。需要快回覆時,用一般 web search 就夠;需要長時推理時,再把背景模式或更深的研究模式加上去。

步驟 2:把外部能力接進來,但先別急著開權限

很多人一上來就想把 GitHub、Stripe、Notion、雲端硬碟全接進去。這個順序通常不太對。比較穩的做法是先確定你的 Agent 到底缺哪一類能力,再決定是加 function tool、local MCP,還是 hosted MCP。

如果你要接的是公開可達、而且本來就有遠端 server 的工具面,OpenAI Agents SDK 現在已經支援 HostedMCPTool。這等於把工具 round-trip 交給 Responses API 處理,你的 Python 程式不用自己手寫 list-tools 和 call-tool 那一層。

import asyncio
from agents import Agent, HostedMCPTool, Runner, WebSearchTool

agent = Agent(
    name="Repository Researcher",
    model="gpt-5.4",
    instructions=(
        "Research software projects. "
        "Use web search for public context, then use MCP when repo-level facts are needed."
    ),
    tools=[
        WebSearchTool(),
        HostedMCPTool(
            tool_config={
                "type": "mcp",
                "server_label": "gitmcp",
                "server_url": "https://gitmcp.io/openai/codex",
                "require_approval": "always",
            }
        ),
    ],
)

async def main():
    result = await Runner.run(
        agent,
        "Find the main language and major folders in the OpenAI Codex repository.",
    )
    print(result.final_output)

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

這裡我故意把 require_approval 設成 always。原因很簡單,研究型 Agent 常常會從「查資料」一路滑向「調外部系統」。你不想等到模型真的開始讀取某個敏感系統時,才想起來自己根本沒做任何審批機制。

OpenAI 在 MCP and Connectors 指南裡也提到,Responses API 會先產生 mcp_list_tools,之後真的調用工具時會看到 mcp_call,如果開了審批,還會多一個 mcp_approval_request。這種可觀測性很重要,因為它讓你可以在 trace 裡把「模型知道了哪些工具」和「模型真的做了哪些動作」分開看。

步驟 3:理解 MCP,不然你只是在「會貼 server_url」

很多教程把 MCP 寫成一個 URL 設定項,看完你會以為它只是「更好用的 function calling」。這種理解太淺了。

MCP 規範真正有價值的地方,在於它讓不同 host 和不同 server 之間有共同語言。規範裡明確定義了 host、client、server 的角色,也把連線方式拆成 stdio、Streamable HTTP 和其他可擴展 transport。這意味著你今天接的是遠端工具,明天也可以換成自己控制的本地 server,而不是整個 Agent 層重寫。

對工程實作來說,我更建議這樣想:

  • 想讓 OpenAI 代你完成遠端調用:優先看 HostedMCPTool
  • 想把本地程序或內網工具接進 Agent:看 MCPServerStdioMCPServerSseMCPServerStreamableHttp
  • 想限制暴露面:先做 tool filtering,再談更複雜的 orchestration

這樣拆的好處是,你不會因為一篇範例用了 HostedMCPTool,就把所有工具都往公開網路上推。對內部系統來說,local transport 往往更合理。

步驟 4:把安全和成本當成功能,不要當補丁

Agent 一旦能查網頁又能碰外部工具,真正的風險才開始出現。這時候 SDK 裡的 guardrails 和 approval flow 就不是可選加分題,而是基礎設施。

OpenAI 的 Guardrails 文檔把邊界說得很清楚:

  • input_guardrails 只會跑在第一個 agent
  • output_guardrails 只會跑在最後輸出的 agent
  • 如果你想在每次 function tool 調用前後都檢查,要用 tool guardrails

這點很容易踩坑。很多人以為自己把 input guardrail 掛上去,整條多 agent 流程都安全了。其實不是。如果你的系統裡有 manager agent、handoff、專家 agent,安全檢查往往要更靠近工具層。

對研究型 Agent,我會先做三個最實用的限制:

  1. Web Search 只負責找最新資料,不負責做敏感操作
  2. MCP 工具預設需要 approval,等你真的信任某幾個工具後再放寬
  3. 工具面太大時,先用 allowed_tools 或 tool search 收斂暴露面

這種做法看起來保守,但長期省事。你越早把權限邊界寫進設計,後面越不容易出現「模型明明只是要幫我整理資料,怎麼開始打第三方 API」這種事故。

進階建議:什麼時候要多 Agent,什麼時候不要

Agents SDK 的 handoff 很吸引人,因為示範看起來都很漂亮。不過我做這類流程時,會先問一個很實際的問題:誰對最終答案負責?

  • 如果你要的是一個總控 Agent,下面掛幾個能力清楚的專家,通常用「agents as tools」比較穩。
  • 如果你真的希望某個專家接手這一輪對話,再用 handoff。

這個差別不只是風格問題。Quickstart 文檔明說,tools 與 handoffs 是兩種不同的控制權模型。前者是 orchestrator 保持主導,後者是把控制權交出去。研究型場景裡,我通常更傾向前者,因為最終輸出需要維持一致的引用風格、風險說明和結論格式。

常見問題與解法

問題 1:工具越接越多,回覆反而更慢

解法: 不要一次把整個工具面都丟給模型。OpenAI 的工具文檔和 SDK 文檔都提到 tool search 與 defer_loading,這類機制就是拿來縮小 schema token 和延遲成本的。MCP server 工具很多時,尤其值得先做這一步。

問題 2:MCP server 可以連上,但模型老是用錯工具

解法: 先改 server_labelserver_description 和 agent instructions,不要急著怪模型。工具命名含糊、描述太廣,是最常見的根因。必要時把 allowed_tools 收窄,讓模型先在小工具集合裡學會正確選擇。

問題 3:Guardrail 明明寫了,為什麼沒擋住

解法: 先檢查你掛的是 agent guardrail 還是 tool guardrail。前者只看流程首尾,後者才會跟著每次 function tool 調用跑。這是官方文檔裡很容易被忽略,但實作上差很多的一條線。

進一步優化的三個方向

1. 讓搜尋和動作分層

研究與執行不要混在同一個工具策略裡。搜尋工具先回答「現在發生了什麼」,MCP 工具再回答「要不要採取行動」。這樣 trace 會乾淨很多,故障排查也容易。

2. 保留可重放的狀態

Quickstart 提到你可以用 result.to_input_list()、session 或 previous_response_id 延續多輪狀態。對研究型工作流來說,這不只是聊天記憶,而是讓你能重放「模型怎麼得到這個結論」的基礎。

3. 盡量連官方或自建的 MCP server

這不是道德潔癖,而是風險控制。OpenAI 的 MCP 指南明確建議優先使用服務方自己託管的 server,例如 Stripe 官方 server,而不是第三方聚合代理。研究型 Agent 尤其要守這條,因為它常常會處理跨系統的資料。

結語

如果你今天只想做一個能 demo 的 Agent,直接把 prompt 和工具塞進去,多半也能跑出點東西。但如果你想做的是團隊真的會用的研究工作流,那就得把三件事分開想:誰負責編排、誰負責調工具、誰負責權限邊界。

OpenAI Agents SDK、Responses API 和 MCP 其實提供了很清楚的分工。麻煩的地方不在功能不夠,而在於我們很容易貪快,把它們全部糊在一起。把這三層拆開之後,你會發現工作流設計反而簡單很多。

如果你想先補 MCP 基礎,再回來做這篇的流程,可以先看站內這兩篇:

參考資料

分享文章

留言評論

0 則評論

暫無評論,搶先發表你的看法吧!

相關文章