如何用 Python 构建多智能体研究助手

TL;DR · AI 摘要
本文详解基于 OpenAI Agents SDK、GPT-5.4 mini 与 Olostep API 构建多智能体研究助手的完整流程,实现自动搜索、评估与结构化报告生成。
核心要点
- 需安装 openai-agents、olostep、pydantic 和 python-dotenv 四个核心包,并配置 OpenAI(≥$5 余额)与 Olo
- 采用 manager-agent 分配任务给 judge-agent(评估证据)与 analyst-agent(执行搜索/抓取/总结),并集成 Olostep
- 最终系统通过 Reflex 构建 Web 应用,支持 PDF 导出,整套流程可在数秒内完成高质量研究产出。
结构提纲
按章节快速跳转。
- §引言
OpenAI Agents SDK 简化了多智能体应用开发,manager-agent 可协调子智能体与工具完成端到端研究任务。
- §环境搭建
需安装 openai-agents、olostep、pydantic 和 python-dotenv,并配置 OpenAI(≥$5 余额)与 Olostep(500 免费请求)API 密钥。
先验证 Olostep Search 与 Scrape 功能是否可用,确保网页搜索结果包含足够内容供后续分析。
定义 manager-agent 作为协调中枢,调用 judge-agent(评估证据)与 analyst-agent(执行搜索/抓取/总结)协同工作。
通过 @function_tool 装饰器将 Olostep API 封装为可调用工具,使用 Pydantic 定义严格输出 schema 以保障报告质量。
使用 Reflex 框架构建交互式前端,集成研究结果展示与 PDF 导出功能,实现端到端可交付产品。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 构建多智能体研究助手
- 技术栈
- OpenAI Agents SDK
- GPT-5.4 mini
- Olostep API
- Pydantic + Reflex
- 智能体角色
- manager-agent:任务协调
- analyst-agent:搜索/抓取
- judge-agent:证据评估
- 关键流程
- 环境配置
- 工具封装
- 工作流编排
- 结果输出与部署
金句 / Highlights
值得收藏与分享的关键句。
OpenAI Agents SDK 的 manager-agent 可自动决定是调用工具、委派子智能体,还是整合中间结果,极大简化了复杂工作流的编排。
Olostep 免费计划提供 500 次成功请求,无需绑定信用卡,足以支撑本文研究助手的完整测试。
manager-agent 通过 delegate(work_to='analyst', task='...') 与 call_tool('olostep_search', query='...') 实现任务分发与工具调用的统一接口。
最终系统可在数秒内生成含引用来源、结构化章节(背景/方法/结果/结论)的研究报告,准确率显著高于单模型直接回答。
标题:如何在 Python 中构建多智能体研究助手
来源链接:https://machinelearningmastery.com/how-to-build-a-multi-agent-research-assistant-in-python/
发布时间:2026-05-21T12:00:31+00:00
Markdown 内容:
本文将介绍如何使用 OpenAI Agents SDK、GPT-5.4 mini 模型以及 Olostep 网页 API 构建一个多智能体 AI 研究助手,涵盖如何将管理型智能体、专业子智能体与实时网页工具整合起来,生成结构化、以网页数据为依据的研究报告。
我们将涵盖以下主题:
- 如何定义一个管理型智能体,协调判断型智能体与分析型智能体,逐步收集并评估证据;
- 如何将 Olostep 的 Answer(问答)、Search(搜索)、Search-with-Scrape(带抓取的搜索)以及 Scrape(抓取)API 作为可调用工具集成进 OpenAI Agents SDK 的工作流中;
- 如何使用 Reflex 构建交互式 Web 应用程序,并以 PDF 格式导出最终的研究报告,从而对外提供该研究助手服务。

如何在 Python 中构建多智能体研究助手
引言
我一直在探索 OpenAI Agents SDK,它已迅速成为我构建智能体(agent-based)AI 应用的首选方式之一。令我印象深刻的是,构建多智能体工作流变得异常简单:只需定义一个管理型智能体,将其与专业子智能体及工具连接起来,然后让其自主决定如何完成任务。
管理型智能体可以将任务委派给其他智能体、直接调用工具,并协调整个研究流程。这使得我们能够构建出远不止生成文本的 AI 应用——它们可以搜索网页、收集信息、组织发现,并生成以事实为依据的输出结果。
在本指南中,我们将使用 OpenAI Agents SDK、GPT-5.4 mini 模型以及 Olostep 网页 API 构建一个多智能体 AI 研究助手。该助手可在数秒内生成一份结构清晰、基于网页数据、易于阅读的研究报告。
本指南还提供了完整代码、Web 应用程序及已部署版本的链接,方便您亲自测试该系统。完成本指南后,您将理解多个智能体如何协同工作,从而从零开始构建一个实用的研究助手。
1. 环境配置
在构建多智能体研究助手之前,我们需要先配置 Python 环境并设置所需的 API 密钥。
我们将使用以下四个主要库:
- openai-agents:用于构建与运行多智能体工作流;
- olostep:用于访问实时网页数据;
- pydantic:用于定义结构化输出;
- python-dotenv:用于从
.env文件中加载 API 密钥。
运行以下命令安装所需库:
pip install -q -U openai-agents olostep python-dotenv pydantic接下来,在项目目录中创建一个 .env 文件,用于安全地存储您的 API 密钥,避免将其硬编码在 Notebook 或应用程序中。
OPENAI_API_KEY=your_openai_api_key
OLOSTEP_API_KEY=your_olostep_api_key您可前往 OpenAI 平台 创建 OpenAI API 密钥。登录您的 OpenAI 账户,进入 API 密钥页面,为本项目生成一个新密钥。在运行示例前,请确保您的 OpenAI 账户已启用计费功能,并至少拥有 5 美元的信用额度;此外,您可能还需完成账户验证以访问最新模型。
对于 Olostep,您可前往 Olostep 官网 免费注册账户,并在控制台中生成 API 密钥。免费套餐提供 500 次成功请求,无需绑定信用卡,足以支持本指南中研究助手的测试使用。
密钥准备就绪后,我们将在 Jupyter Notebook 中开始编码:导入所需库并加载环境变量。此配置将为 Notebook 接入 OpenAI、Olostep、结构化输出与追踪(tracing)功能做好准备。
import json
import os
from datetime import datetime
from typing import Any
from dotenv import load_dotenv
from IPython.display import Markdown, display
from olostep import Olostep
from pydantic import BaseModel, Field
from agents import (
Agent,
Runner,
custom_span,
flush_traces,
function_tool,
gen_trace_id,
trace,
)
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OLOSTEP_API_KEY = os.getenv("OLOSTEP_API_KEY")2. 测试 Olostep 搜索与网页抓取功能
在构建完整的多智能体工作流之前,建议先测试 Olostep 是否能成功搜索网页并抓取返回页面的内容。这一步可验证您的 API 密钥是否有效,并确认搜索结果是否包含足够内容以供后续分析。
Olostep 的 Search(搜索)API 特别实用,因为它支持在返回搜索结果的同时进行网页抓取。您不仅能获得页面标题、摘要和链接,还可要求 Olostep 抓取返回的 URL,并以 Markdown 等格式提供提取后的内容。
这意味着智能体可直接使用高质量页面内容,而不仅限于搜索摘要;同时,您也无需自行构建独立的“搜索+抓取”流程,从而节省大量开发时间。
client = Olostep(api_key=OLOSTEP_API_KEY)
search = client.searches.create(
query="What are the most important recent developments in AI agents for business research?",
limit=5,
scrape_options={"formats": ["markdown"], "timeout": 25},
)
for link in search.links:
print(link["url"], "-", len(link.get("markdown_content") or ""), "chars")这会告知 Olostep 抓取每页返回的内容,并以 Markdown 格式提供提取出的信息。Markdown 格式很有用,因为它在保留内容可读性的同时,去除了页面中不必要的杂乱元素。超时值(timeout value)为 Olostep 提供了足够的时间来获取并处理每一页内容。
搜索完成后,我们将遍历返回的链接,打印每个 URL 及其从页面中提取的字符数量。
3. 添加辅助函数
在创建智能体(agents)和工具(tools)之前,我们需要先添加一些辅助函数。这些工具函数使其余代码更加简洁,并有助于调试整个工作流。
这些辅助函数将处理以下六项任务:
- 检查 Olostep API 密钥是否已设置
- 创建一个可复用的 Olostep 客户端
- 将 SDK 响应转换为标准的 Python 字典
- 压缩大型 JSON 输出,便于检查
- 添加当前日期和年份作为智能体的上下文信息
- 将搜索结果规范化为更简洁的格式,便于智能体使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class OlostepError(RuntimeError):
"""当 Olostep SDK 请求失败时抛出。"""
def require_olostep_key() -> str:
if not OLOSTEP_API_KEY:
raise OlostepError(
"未设置 OLOSTEP_API_KEY。请将其添加至 .env 文件,并重新运行设置单元格。"
)
return OLOSTEP_API_KEY
def get_olostep_client() -> Olostep:
return Olostep(api_key=require_olostep_key())
def sdk_result_to_dict(result: Any) -> dict[str, Any]:
if hasattr(result, "model_dump"):
return result.model_dump()
if hasattr(result, "__dict__"):
return {
key: value
for key, value in vars(result).items()
if not key.startswith("_")
}
return {"value": str(result)}
def compact_json(data: Any, max_chars: int = 8000) -> str:
text = json.dumps(data, ensure_ascii=False, indent=2, default=str)
if len(text) <= max_chars:
return text
return text[:max_chars] + "\n... [已截断]"
def current_date_context() -> str:
return datetime.now().strftime("%Y年%m月%d日")
def current_year_context() -> str:
return str(datetime.now().year)
def normalize_search_links(
links: list[dict[str, Any]], limit: int = 8
) -> list[dict[str, Any]]:
rows = []
for link in links[:limit]:
markdown = link.get("markdown_content") or ""
rows.append(
{
"title": link.get("title") or "无标题",
"url": link.get("url") or "",
"description": link.get("description") or "",
"markdown_chars": len(markdown),
"markdown_preview": markdown[:1500] if markdown else "",
}
)
return rows4. 定义结构化输出模型
接下来,定义智能体将返回的结构化输出。这些模型使工作流更加可靠,因为每个智能体都必须以一致的格式返回信息。
判断智能体(judge agent)使用 Judgment 模型来决定已收集的证据是否足够充分;分析智能体(analyst agent)则使用 MarkdownResearchReport 模型,将最终报告以格式良好的 Markdown 形式返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Judgment(BaseModel):
is_good_enough: bool = Field(
description="该答案是否足以满足用户查询需求(即评分 ≥ 0.85)。"
)
score: float = Field(ge=0, le=1, description="质量评分,范围为 0 至 1。")
reason: str = Field(description="对该决策的简要说明。")
missing_information: list[str] = Field(
default_factory=list, description="需要补充的重要信息缺口。"
)
class MarkdownResearchReport(BaseModel):
markdown_report: str = Field(
description="完整的 Markdown 报告,包含规范的标题、清晰的分析、读者友好的结构以及引用来源。"
)Judgment 作为质量控制模式,帮助判断智能体决定已收集的证据是否足够充分,或是否需要让管理智能体(manager agent)继续搜索。
MarkdownResearchReport 定义了最终的研究输出。由于最终应用仅需完整的报告内容,该模型仅包含一个 markdown_report 字段,而非额外的元数据字段。这使得输出更简洁,也更便于在笔记本、Web 应用及 PDF 导出中展示。
5. 创建 Olostep 工具函数
现在,我们来创建管理智能体在研究过程中可调用的工具。这些工具封装了 Olostep 的 Answer API(问答 API)、Search API(搜索 API)、Search with Scrape(搜索并抓取)以及 Scrape API(抓取 API)。
每个工具都包含追踪(tracing)跨度(spans),以便您可在 OpenAI 追踪查看器中检查执行期间发生的情况。这对于调试非常有用,因为您可以清楚看到调用了哪个工具、接收了什么输入,以及管理智能体在工作流中是如何推进的。
问答查询工具
该工具向 Olostep 请求对用户研究问题的快速回答,作为工作流的第一步,在决定是否需要进一步研究前使用。
1
2
3
4
5
6
7
8
9
10
@function_tool
async def answer_query(query: str) -> str:
"""使用 Olostep Answer API 回答用户的自然语言研究问题。"""
try:
with custom_span("olostep.answer_query", {"query": query}):
result = get_olostep_client().answers.create(task=query)
return compact_json(sdk_result_to_dict(result))
except Exception as exc:
raise OlostepError(f"Olostep Answer API 调用失败:{exc}") from exc网页搜索工具
该工具执行标准网页搜索,并返回规范化后的结果。当助手需要在抓取具体页面前发现更多来源时,此工具非常有用。
输出被有意设计得简洁紧凑:工具不会返回完整的原始 API 响应,而是仅返回查询语句及清理后的搜索结果列表。这使得管理智能体更易于阅读响应内容,同时减少了不必要的上下文开销。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@function_tool
async def search_web(query: str, limit: int = 8) -> str:
"""使用 Olostep Search 进行网页搜索,并返回规范化结果。"""
try:
with custom_span("olostep.search_web", {"query": query, "limit": limit}):
search = get_olostep_client().searches.create(
query=query,
limit=limit,
)data = sdk_result_to_dict(search)
return compact_json(
{
"query": query,
"results": normalize_search_links(
data.get("links", []),
limit=limit,
),
}
)
except Exception as exc:
raise OlostepError(f"Olostep Search API failed: {exc}") from exc使用 Scraping 工具进行搜索
该工具可在一步内完成网页搜索并抓取返回页面的内容,为研究助手提供比仅靠搜索摘要更丰富的证据。
这是项目中最重要的工具之一,因为它允许智能体通过一次调用同时获取链接和页面内容。无需先进行网页搜索、手动选择 URL,再逐一抓取各页面,该工具可直接从已发现的页面中返回可用的 Markdown 格式内容。
@function_tool
async def search_with_scrape(query: str, limit: int = 5) -> str:
"""使用 Olostep Search with Scrape 在网页中搜索并抓取每个返回链接。"""
scrape_options = {
"formats": ["markdown"],
"timeout": 25,
}
try:
with custom_span(
"olostep.search_with_scrape",
{
"query": query,
"limit": limit,
"scrape_options": scrape_options,
},
):
search = get_olostep_client().searches.create(
query=query,
limit=limit,
scrape_options=scrape_options,
)
data = sdk_result_to_dict(search)
return compact_json(
{
"query": query,
"results": normalize_search_links(
data.get("links", []),
limit=limit,
),
},
max_chars=12000,
)
except Exception as exc:
raise OlostepError(f"Olostep Search with Scrape failed: {exc}") from exc抓取 URL 工具
该工具用于抓取单个 URL 并返回精简后的页面内容。管理智能体(manager agent)在需要从选定来源获取更深入证据时会使用此工具。
例如,管理智能体可先使用 search_web 找到相关页面,再用 scrape_url 从最有价值的链接中提取完整内容。
@function_tool
async def scrape_url(url: str) -> str:
"""使用 Olostep 抓取单个 URL 并返回精简后的页面内容。"""
try:
with custom_span(
"olostep.scrape_url",
{
"url": url,
"formats": ["markdown"],
},
):
scrape = get_olostep_client().scrapes.create(
url=url,
formats=["markdown"],
)
return compact_json(
{
"url": url,
"scrape": sdk_result_to_dict(scrape),
},
max_chars=10000,
)
except Exception as exc:
raise OlostepError(f"Olostep Scrape API failed: {exc}") from exc这些工具为管理智能体提供了多种收集证据的方式:可先快速获取初步答案;再通过搜索寻找更多来源;使用“带抓取的搜索”获取更丰富的上下文;或在需要细节时直接抓取特定 URL。
6. 构建专业智能体
工作流中使用了两个专业智能体:一个评估智能体(judge agent)和一个分析智能体(analyst agent)。
评估智能体用于判断所收集的证据是否足够有力,以回答用户的问题;分析智能体则将经批准的证据转化为一份精炼的 Markdown 格式研究报告。
首先定义两个专业智能体共同使用的模型:
MODEL = "gpt-5.4-mini"评估智能体
评估智能体用于评估答案质量。它会检查答案是否具体、时效性强、有可靠来源支撑,以及是否足够完整,从而决定是否可以终止研究流程。
这一点至关重要,因为管理智能体不应基于薄弱证据生成最终报告。若答案模糊、过时、缺乏支撑,或缺少关键细节,评估智能体将拒绝该答案,管理智能体则可继续搜索。
judge_agent = Agent(
name="Judge agent",
model=MODEL,
instructions=(
"你需判断所提供的答案是否足以回应原始研究问题。"
"优先奖励直接、具体、有可靠来源支撑的答案;拒绝模糊、陈旧或缺乏支撑的答案。"
"要求严格:仅当评分 ≥ 0.85 且证据能直接、具体地回答问题(含具体来源内容、领域特定细节及适当时效性)时,才可标记 is_good_enough 为 true。"
"对于时事、产品状态、政策、定价或可能变动的事实性主张,必须引用近期的一手或高度权威来源。"
"若存在任何关键缺失,不得标记证据为充分。"
"评分标准如下:"
"0.85–1.0:证据充分,可终止研究,具备强来源支撑且无关键缺失;"
"0.75–0.84:证据较强,但仍缺失一项重要来源、细节、时效性验证或覆盖范围;"
"0.50–0.74:存在部分相关证据,但需进一步研究;"
"0.25–0.49:证据薄弱、模糊、陈旧或关联性弱;"
"低于 0.25:仅适用于空内容、不可用或基本无关的证据。"
"即使证据看似合理或方向正确,也不应标记为充分。"
"仅返回结构化判断结果。"
),
output_type=Judgment,
)评估智能体返回一个 Judgment 对象,包含:证据是否充分、质量评分、简短理由,以及仍需补充的信息。
分析智能体
分析智能体负责撰写最终的 Markdown 报告,将收集到的证据转化为结构清晰、易于浏览、具备专业水准的研究简报,包含明确章节、来源注释与引用。
该智能体的职责是使输出内容对专业读者真正有用。它并非简单汇总原始工具输出,而是将发现整合为一份完整报告:阐明主题、突出关键证据,并标注所用来源。
analyst_agent = Agent(
name="Analyst agent",
model=MODEL,
instructions=(
"你需基于证据撰写一份规范的 Markdown 格式研究报告。"
"面向希望获得任何主题下清晰、精炼研究简报的专业读者。"
"报告应根据用户问题进行适配,markdown_report 内容须充实、易于扫描,仅使用以下通用章节:"
),
)“执行摘要、关键发现、背景、证据回顾、详细分析、影响、来源注释和参考文献。”
“若主题为事件驱动型,请将时间线细节整合进‘背景’或‘详细分析’部分,而非单独设立‘时间线’章节。”
“若主题为比较型,请在‘详细分析’部分中加入一个简洁的对比表格。”
“不要包含标题为‘局限性’、‘后续步骤’、‘建议’或‘行动项’的章节。”
“避免使用空洞的免责声明,如‘我依赖于……’;应将来源质量信息自然地融入‘来源注释’中。”
“使用简短段落,必要时采用项目符号列表,并以 Markdown 链接或 URL 项目符号形式添加引用。”
“提供充分背景信息,确保非专业读者能理解该议题、其重要性以及支持该结论的证据。”
“报告中不得使用表情符号、返回箭头符号、反向链接图标或任何装饰性图标。”
“在‘参考文献’部分,仅以纯 Markdown 项目符号或编号条目列出来源名称与 URL。”
“仅返回结构化报告。”
),
output_type=MarkdownResearchReport,
)
分析代理返回一个 MarkdownResearchReport 对象,其中仅包含一个字段:markdown_report。这使得最终输出保持简洁,因为完整标题、摘要、发现、分析、来源注释及参考文献均包含在该 Markdown 报告内部。
7. 创建管理代理
管理代理是整个系统的协调者,负责控制完整的研究流程,并决定下一步应调用哪个工具或专家代理。
工作流程遵循以下模式:
- 首先通过 Olostep Answer API 快速获取初步答案
- 立即调用判断代理评估该答案是否足够可靠
- 若不足,则执行带网页抓取的搜索以获取更强证据
- 再次调用判断代理评估
- 若证据仍显薄弱,则进行多次定向搜索,并抓取最相关的页面
- 最后调用分析代理撰写最终报告
首先,将判断代理与分析代理转换为工具,以便管理代理在流程中调用它们:
judge_tool = judge_agent.as_tool(
tool_name="judge_answer_quality",
tool_description="评估某个答案或证据是否足以回应原始研究问题。",
)
analyst_tool = analyst_agent.as_tool(
tool_name="write_markdown_research_report",
tool_description="基于所收集的证据,撰写最终结构化 Markdown 研究报告。",
)接下来定义管理代理。该代理不依赖自身记忆作答,而是严格遵循明确的研究流程:作答 → 判断 → 搜索 → 再判断 → 必要时抓取 → 最终撰写报告。
manager_agent = Agent(
name="Manager research agent",
model=MODEL,
instructions=(
f"Current date: {current_date_context()}\n"
f"Current year: {current_year_context()}\n\n"
"You are the orchestrator for a multi-agent research assistant. You must manage the workflow, "
"not answer from your own memory. Follow this policy exactly:\n"
"1. Always call answer_query first to get a simple initial answer for the user's question.\n"
"2. Immediately call judge_answer_quality on the original question plus the answer_query result. "
"If the judge returns is_good_enough=true and score >= 0.85, stop researching and call "
"write_markdown_research_report with the question, answer result, and judgment.\n"
"3. If the first judgment is weak, call search_with_scrape for the original question. "
"Immediately call judge_answer_quality again on the original question plus the answer_query result, "
"first judgment, and search_with_scrape result. If this second judge returns is_good_enough=true "
"and score >= 0.85, stop researching and call write_markdown_research_report with all evidence.\n"
"4. If the second judgment is still weak, do not call the judge again. Run multiple targeted "
"search_web calls first, using the judge's missing_information to form the searches. Inspect the "
"search results, choose at least the top 3 relevant source URLs most likely to answer the missing "
"points, then call scrape_url on each of those top 3 pages. Scrape more than 3 only if clearly needed.\n"
"5. Call write_markdown_research_report exactly once at the end, using every answer, judgment, "
"search result, and scraped page. The analyst must produce the final MarkdownResearchReport.\n"
"6. Return only the final MarkdownResearchReport. Do not return a casual chat answer, tool transcript, or plan."
),
tools=[
answer_query,
judge_tool,
search_with_scrape,
search_web,
scrape_url,
analyst_tool,
],
output_type=MarkdownResearchReport,
)管理代理是系统的核心,负责判断何时初步答案已足够,何时需进一步收集证据,以及何时应调用分析代理生成最终报告。
关键在于:管理代理不依赖单次工具调用。它首先获取快速答案,评估其质量,仅在必要时深入研究。这种机制确保流程高效,同时仍能为复杂问题收集更有力的证据。
8. 运行研究助手并启用追踪
最终函数调用管理代理并返回结构化研究报告,同时生成一个 OpenAI 追踪 ID,便于检查完整工作流,包括管理代理的决策、专家代理调用、工具使用情况及 Olostep 跨度信息。
追踪功能在调试多代理系统时尤为有用,因为它能清晰展示每一步的操作细节:管理代理是否遵循了既定流程、调用了哪些工具、收集了哪些证据、判断代理如何评估答案,以及分析代理何时生成了最终报告。
51 def openai_trace_url(trace_id: str) -> str:
52 return f"https://platform.openai.com/logs/trace?trace_id={trace_id}"
async def run_research_assistant(query: str) -> MarkdownResearchReport:
if not OPENAI_API_KEY:
raise RuntimeError(
"OPENAI_API_KEY 未设置。请将其添加至 .env 文件并重新运行设置单元格。"
)
require_olostep_key()
trace_id = gen_trace_id()
print("OpenAI trace ID:", trace_id)
print("OpenAI trace URL:", openai_trace_url(trace_id))
current_date = current_date_context()
current_year = current_year_context()
prompt = f"""
当前日期:
{current_date}
当前年份:
{current_year}
研究问题:
{query}
请针对用户的特定问题,返回一份内容详实、易于阅读的 Markdown 格式研究报告。请严格遵循以下工作流程:
- 首先使用 answer_query 获取一个初步的简要答案;
- 紧接着使用 judge agent 判断是否应停止或继续;
- 若首次判断认为答案不够充分,则运行 search_with_scrape;
- 在 search_with_scrape 完成后,立即再次使用 judge agent 判断是否应停止或继续;
- 若第二次判断仍认为证据不足,则不再重复判断,而是执行多次有针对性的 search_web 调用,从搜索结果中至少选取前 3 个最相关的源 URL,并对这 3 个页面进行内容抓取以获取上下文;
- 最后由 analyst agent 综合所有 answer、judge、search 和 scrape 的结果,撰写最终的 Markdown 报告。注意:报告中无需包含 Limitations(局限性)或 Next Steps(后续步骤)部分。
"""
with trace(
workflow_name="multi_agent_research_assistant_olostep",
trace_id=trace_id,
metadata={
"query": query,
"notebook": "multi_agent_research_assistant_openai_agents_olostep",
},
):
with custom_span("manager.run", {"query": query}):
result = await Runner.run(manager_agent, prompt, max_turns=30)
flush_traces()
print(
"Trace 已刷新。请打开上方 URL 查看 manager、专业 agent、工具及 Olostep 的 span 数据。"
)
return result.final_output该函数首先检查两个 API 密钥是否均已就绪,随后生成 trace ID 并打印 trace URL,以便您在 OpenAI trace 查看器中查看完整执行过程。
trace() 代码块用于将整个工作流归为一组,而 custom_span() 则用于标记 manager agent 的运行阶段。由于 Olostep 工具本身也使用了自定义 span,因此您可以在同一视图中同时观察到 agent 的决策过程与 API 调用详情。
最后,flush_traces() 将 trace 数据发送至 OpenAI,使本次运行结果可供审查。
9. 测试多 Agent 研究助手
现在,请使用一个示例研究问题测试完整工作流。助手将依次运行 manager agent、收集证据、评估证据质量,并最终返回结构化的 Markdown 报告。
example_query = "What's going on with OpenAI's Sora shutting down?"
report = await run_research_assistant(example_query)
display(Markdown(report.markdown_report))运行该单元格时,Notebook 将打印出 OpenAI trace ID 和 trace URL:
OpenAI trace ID: trace_45f3333363da420dbcefc8bb8819224c
OpenAI trace URL: https://platform.openai.com/logs/trace?trace_id=trace_45f3333363da420dbcefc8bb8819224c点击 trace URL,即可在 OpenAI trace 查看器中打开本次运行记录。您可借此查看 manager agent、judge agent、analyst agent、Olostep 工具及网页抓取调用等整个执行路径。
trace 的价值在于它清晰展示了实际的编排过程:您可以看到 manager agent 何时启动 answer_query,何时将结果提交给 judge agent,以及 judge agent 如何判断证据是否充分。若首次答案不足,trace 也会记录 manager agent 何时调用 search_with_scrape 或执行定向抓取以获取更高质量的证据。

manager agent 完成研究流程后,Notebook 将展示最终的 Markdown 报告:

最终报告采用清晰、易读的格式,包含执行摘要、关键发现、背景信息、分析内容、来源说明及参考文献。
若您在运行 Notebook 或复现上述结果时遇到问题,可查阅 GitHub 上的完整 Jupyter Notebook。其中包含完整的环境配置、辅助函数、agent 定义、工具调用、trace 流程及示例输出:multi_agent_research_assistant_openai_agents_olostep.ipynb
10. 使用 Reflex 构建 Web UI
在 Notebook 中测试完代码后,可借助 Reflex(一个用于构建交互式用户界面的 Python Web 框架)将研究助手封装为简易 Web 应用。
该 Web 应用旨在提供一个简洁的界面,使用户能够:
- 输入研究问题;
- 启动多 Agent 工作流;
- 查看 agent 活动日志;
- 阅读最终研究报告;
- 将报告下载为 PDF 文件。
您可在项目仓库中找到该应用的完整代码:Multi-Agent-Research-Assistant/app
首先克隆项目仓库:
git clone https://github.com/kingabzpro/Multi-Agent-Research-Assistant.git进入项目目录并安装所需依赖:
cd Multi-Agent-Research-Assistant
pip install -r requirements.txt接着,根据提供的模板创建 .env 文件,并填入您的 API 密钥:
OPENAI_API_KEY=your_openai_api_key
OLOSTEP_API_KEY=your_olostep_api_key
OPENAI_MODEL=gpt-5.4-mini最后,运行 Reflex 应用:
reflex run应用启动后,打开终端中打印出的本地 URL,通常为:
1 http://localhost:3000
此时,您已拥有一个可正常运行的多智能体研究助手 Web 界面。
该界面设计简洁、响应迅速且实用性强。当您输入问题并点击“搜索”按钮后,应用将实时显示工作流日志,便于您跟踪研究助手的执行过程。

助手首先调用 Olostep Answer API 获取初步答案,随后将该答案及证据发送给“评判者”智能体,以评估答案是否足够可靠。若评判者认为还需补充更多证据,“管理者”智能体将继续执行网页搜索、网页内容抓取及额外信源收集等任务,最终将全部信息交由“分析师”智能体生成最终报告。

最终报告将以清晰、专业的格式呈现,便于阅读。您还可将生成的研究报告下载为 PDF 文件,方便后续保存、分享或审阅。

若您不想本地构建应用,仅希望快速体验,可直接使用已部署的 Hugging Face Space:Multi-Agent Research Assistant – 由 kingabzpro 创建的 Hugging Face Space
总结
构建该多智能体研究助手的过程表明,借助专业智能体与多种工具,轻松即可实现一个实用的智能体工作流。系统不再依赖每次均执行一次昂贵且庞大的整体研究流程,而是由“管理者”智能体根据证据质量动态选择最优路径。
该工作流在速度、成本与准确性之间取得了良好平衡:首先调用 Olostep Answer API 快速获取初步响应;若评判者给出较高评分,“分析师”智能体将立即生成最终报告,从而确保简单任务快速、低成本完成。
若评判者认为首版答案不够可靠,“管理者”智能体将启动“搜索+抓取”流程,以获取更丰富的证据,而无需直接进入更深入、更昂贵的研究环节。评判者再次评估证据质量,若达标,则由分析师撰写最终报告。
仅当证据仍显不足时,“管理者”智能体才会执行针对性搜索并抓取精选页面。这使得系统在面对复杂、时效性强或缺乏关键背景信息的问题时,仍能生成更准确的报告。
最值得称道的是:不同查询的耗时与成本各不相同——简单问题可快速完成,而复杂问题则在需要时自动扩展研究深度。这使该助手更具效率、可靠性,并更贴合真实世界的研究工作流。
##### 暂无评论。