T
traeai
登录
返回首页
Machine Learning Mastery

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

8.7Score
如何用 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 导出,整套流程可在数秒内完成高质量研究产出。

结构提纲

按章节快速跳转。

  1. OpenAI Agents SDK 简化了多智能体应用开发,manager-agent 可协调子智能体与工具完成端到端研究任务。

  2. 需安装 openai-agents、olostep、pydantic 和 python-dotenv,并配置 OpenAI(≥$5 余额)与 Olostep(500 免费请求)API 密钥。

  3. 先验证 Olostep Search 与 Scrape 功能是否可用,确保网页搜索结果包含足够内容供后续分析。

  4. 定义 manager-agent 作为协调中枢,调用 judge-agent(评估证据)与 analyst-agent(执行搜索/抓取/总结)协同工作。

  5. 通过 @function_tool 装饰器将 Olostep API 封装为可调用工具,使用 Pydantic 定义严格输出 schema 以保障报告质量。

  6. 使用 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 可自动决定是调用工具、委派子智能体,还是整合中间结果,极大简化了复杂工作流的编排。

    第 2 节 Introduction

    ⬇︎ 下载 PNG𝕏 分享到 X
  • Olostep 免费计划提供 500 次成功请求,无需绑定信用卡,足以支撑本文研究助手的完整测试。

    第 1 节 Set Up the Environment

    ⬇︎ 下载 PNG𝕏 分享到 X
  • manager-agent 通过 delegate(work_to='analyst', task='...') 与 call_tool('olostep_search', query='...') 实现任务分发与工具调用的统一接口。

    第 4 节 Multi-Agent Architecture

    ⬇︎ 下载 PNG𝕏 分享到 X
  • 最终系统可在数秒内生成含引用来源、结构化章节(背景/方法/结果/结论)的研究报告,准确率显著高于单模型直接回答。

    第 6 节 Web App Deployment

    ⬇︎ 下载 PNG𝕏 分享到 X
#多智能体系统#OpenAI Agents SDK#Olostep#GPT-5.4 mini#AI 工程实践
打开原文

标题:如何在 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 格式导出最终的研究报告,从而对外提供该研究助手服务。
图1:如何在 Python 中构建多智能体研究助手

如何在 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 密钥。

运行以下命令安装所需库:

bash
pip install -q -U openai-agents olostep python-dotenv pydantic

接下来,在项目目录中创建一个 .env 文件,用于安全地存储您的 API 密钥,避免将其硬编码在 Notebook 或应用程序中。

env
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)功能做好准备。

python
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 等格式提供提取后的内容。

这意味着智能体可直接使用高质量页面内容,而不仅限于搜索摘要;同时,您也无需自行构建独立的“搜索+抓取”流程,从而节省大量开发时间。

python
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

python
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 rows

4. 定义结构化输出模型

接下来,定义智能体将返回的结构化输出。这些模型使工作流更加可靠,因为每个智能体都必须以一致的格式返回信息。

判断智能体(judge agent)使用 Judgment 模型来决定已收集的证据是否足够充分;分析智能体(analyst agent)则使用 MarkdownResearchReport 模型,将最终报告以格式良好的 Markdown 形式返回。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

python
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

python
@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

python
@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,
            )
python
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 格式内容。

python
@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 从最有价值的链接中提取完整内容。

python
@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 格式研究报告。

首先定义两个专业智能体共同使用的模型:

python
MODEL = "gpt-5.4-mini"

评估智能体

评估智能体用于评估答案质量。它会检查答案是否具体、时效性强、有可靠来源支撑,以及是否足够完整,从而决定是否可以终止研究流程。

这一点至关重要,因为管理智能体不应基于薄弱证据生成最终报告。若答案模糊、过时、缺乏支撑,或缺少关键细节,评估智能体将拒绝该答案,管理智能体则可继续搜索。

python
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 报告,将收集到的证据转化为结构清晰、易于浏览、具备专业水准的研究简报,包含明确章节、来源注释与引用。

该智能体的职责是使输出内容对专业读者真正有用。它并非简单汇总原始工具输出,而是将发现整合为一份完整报告:阐明主题、突出关键证据,并标注所用来源。

python
analyst_agent = Agent(
    name="Analyst agent",
    model=MODEL,
    instructions=(
        "你需基于证据撰写一份规范的 Markdown 格式研究报告。"
        "面向希望获得任何主题下清晰、精炼研究简报的专业读者。"
        "报告应根据用户问题进行适配,markdown_report 内容须充实、易于扫描,仅使用以下通用章节:"
    ),
)

“执行摘要、关键发现、背景、证据回顾、详细分析、影响、来源注释和参考文献。”

“若主题为事件驱动型,请将时间线细节整合进‘背景’或‘详细分析’部分,而非单独设立‘时间线’章节。”

“若主题为比较型,请在‘详细分析’部分中加入一个简洁的对比表格。”

“不要包含标题为‘局限性’、‘后续步骤’、‘建议’或‘行动项’的章节。”

“避免使用空洞的免责声明,如‘我依赖于……’;应将来源质量信息自然地融入‘来源注释’中。”

“使用简短段落,必要时采用项目符号列表,并以 Markdown 链接或 URL 项目符号形式添加引用。”

“提供充分背景信息,确保非专业读者能理解该议题、其重要性以及支持该结论的证据。”

“报告中不得使用表情符号、返回箭头符号、反向链接图标或任何装饰性图标。”

“在‘参考文献’部分,仅以纯 Markdown 项目符号或编号条目列出来源名称与 URL。”

“仅返回结构化报告。”

),

output_type=MarkdownResearchReport,

)

分析代理返回一个 MarkdownResearchReport 对象,其中仅包含一个字段:markdown_report。这使得最终输出保持简洁,因为完整标题、摘要、发现、分析、来源注释及参考文献均包含在该 Markdown 报告内部。

7. 创建管理代理

管理代理是整个系统的协调者,负责控制完整的研究流程,并决定下一步应调用哪个工具或专家代理。

工作流程遵循以下模式:

  1. 首先通过 Olostep Answer API 快速获取初步答案
  2. 立即调用判断代理评估该答案是否足够可靠
  3. 若不足,则执行带网页抓取的搜索以获取更强证据
  4. 再次调用判断代理评估
  5. 若证据仍显薄弱,则进行多次定向搜索,并抓取最相关的页面
  6. 最后调用分析代理撰写最终报告

首先,将判断代理与分析代理转换为工具,以便管理代理在流程中调用它们:

python
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 研究报告。",
)

接下来定义管理代理。该代理不依赖自身记忆作答,而是严格遵循明确的研究流程:作答 → 判断 → 搜索 → 再判断 → 必要时抓取 → 最终撰写报告。

python
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 跨度信息。

追踪功能在调试多代理系统时尤为有用,因为它能清晰展示每一步的操作细节:管理代理是否遵循了既定流程、调用了哪些工具、收集了哪些证据、判断代理如何评估答案,以及分析代理何时生成了最终报告。

python
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 报告。

python
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:

code
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 或执行定向抓取以获取更高质量的证据。

Image 2: 使用 OpenAI Agents SDK 与 Olostep 构建多 Agent 研究助手

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

Image 3: 使用 OpenAI Agents SDK 与 Olostep 构建多 Agent 研究助手

最终报告采用清晰、易读的格式,包含执行摘要、关键发现、背景信息、分析内容、来源说明及参考文献。

若您在运行 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

首先克隆项目仓库:

bash
git clone https://github.com/kingabzpro/Multi-Agent-Research-Assistant.git

进入项目目录并安装所需依赖:

bash
cd Multi-Agent-Research-Assistant
pip install -r requirements.txt

接着,根据提供的模板创建 .env 文件,并填入您的 API 密钥:

env
OPENAI_API_KEY=your_openai_api_key
OLOSTEP_API_KEY=your_olostep_api_key
OPENAI_MODEL=gpt-5.4-mini

最后,运行 Reflex 应用:

bash
reflex run

应用启动后,打开终端中打印出的本地 URL,通常为:

1 http://localhost:3000

此时,您已拥有一个可正常运行的多智能体研究助手 Web 界面。

该界面设计简洁、响应迅速且实用性强。当您输入问题并点击“搜索”按钮后,应用将实时显示工作流日志,便于您跟踪研究助手的执行过程。

图4:使用 OpenAI Agents SDK 与 Olostep 构建多智能体研究助手

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

图5:使用 OpenAI Agents SDK 与 Olostep 构建多智能体研究助手

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

图6:使用 OpenAI Agents SDK 与 Olostep 构建多智能体研究助手

若您不想本地构建应用,仅希望快速体验,可直接使用已部署的 Hugging Face Space:Multi-Agent Research Assistant – 由 kingabzpro 创建的 Hugging Face Space

总结

构建该多智能体研究助手的过程表明,借助专业智能体与多种工具,轻松即可实现一个实用的智能体工作流。系统不再依赖每次均执行一次昂贵且庞大的整体研究流程,而是由“管理者”智能体根据证据质量动态选择最优路径。

该工作流在速度、成本与准确性之间取得了良好平衡:首先调用 Olostep Answer API 快速获取初步响应;若评判者给出较高评分,“分析师”智能体将立即生成最终报告,从而确保简单任务快速、低成本完成。

若评判者认为首版答案不够可靠,“管理者”智能体将启动“搜索+抓取”流程,以获取更丰富的证据,而无需直接进入更深入、更昂贵的研究环节。评判者再次评估证据质量,若达标,则由分析师撰写最终报告。

仅当证据仍显不足时,“管理者”智能体才会执行针对性搜索并抓取精选页面。这使得系统在面对复杂、时效性强或缺乏关键背景信息的问题时,仍能生成更准确的报告。

最值得称道的是:不同查询的耗时与成本各不相同——简单问题可快速完成,而复杂问题则在需要时自动扩展研究深度。这使该助手更具效率、可靠性,并更贴合真实世界的研究工作流。

##### 暂无评论。

AI 可能会生成不准确的信息,请核实重要内容

如何用 Python 构建多智能体研究助手 | Machine Learning Mastery | traeai