GPT Researcher
assafelovic/gpt-researcher项目目录
项目简介
GPT Researcher 将研究问题拆为搜索子查询,异步搜集网页,也可读取本地资料,再筛选上下文生成带引用的报告。普通研究、详细报告和深度研究有不同入口;当前普通链的重点是子问题规划、并行采集、上下文选择和来源保留。
如何写进简历
竞知 · 制造业竞品情报研究平台 | 场景化示例
项目描述:基于 GPT Researcher,面向制造业产品与市场团队,跟踪竞品型号、性能和量产交付动态,将公告、产品资料与行业报道整理为可回查的竞品简报。
技术栈:Python、FastAPI、asyncio、LangChain、BM25
主要工作:
- 并发研究与重复抓取控制:利用
GPT Researcher的子问题规划和asyncio并发采集,复用初搜材料并以共享 URL 集减少重复抓取,将竞品型号、性能和交付动态汇入研究上下文。 - 多策略上下文筛选:基于统一入口接入
BM25、向量相似度与Jev评分,按策略处理少量资料直返和关键词回退,通过分块与结果数量约束报告上下文规模。 - 来源引用与空资料处理:向写作模型同时传递标题、来源 URL 和筛选正文,约束竞品结论引用已有资料;无研究上下文时停止写作,为情报简报保留来源回查路径。
面试题与回答
如何设计能检索、整合证据并生成报告的 Deep Research Agent?
展开收起
核心回答
我会把研究任务拆成查询规划、并发资料采集、上下文筛选和报告写作,并让来源随内容一起传递。
GPT Researcher的普通网页研究就是这条路线:先初搜了解主题,再生成子查询,读入初搜来源,并用asyncio.gather并发处理各个子查询;同一研究实例共享已访问 URL 集合,减少重复抓取。最后将相关内容汇总到context,交给报告生成器写作并引用来源。这样能把一次开放式调研组织为可执行的有限任务。若还要求反复发现证据缺口、追查争议和决定何时停止,我会在此基础上增加证据状态与补查控制;不能把“并发搜完一批问题”直接当成已经完成了事实交叉验证。
1. 先用初搜校准研究问题,再执行子查询
GPTResearcher用Python协调检索器、网页抓取器、上下文筛选器和LLM报告生成器。以report_source="web"的普通research_report为例,ResearchConductor先用第一个检索器搜索原问题,将初搜结果交给plan_research_outline生成子查询。普通研究还会把原问题加入待研究列表;subtopic_report则不再追加它,避免子主题又展开成整个主问题。初搜不只是规划材料。在执行子查询前,这条链还会通过正常的正文获取路径读取初搜来源,形成
initial_context,再并发运行各个_process_sub_query。这样,规划时看到的重要来源不会仅因后续换了关键词而被遗漏。所有非空子查询上下文连同初搜上下文一起合并。普通研究编排源码。asyncio.gather调度的是子查询协程,并不意味着每个查询都拥有一个独立的多代理工作流。它本身也不提供并发上限。若用于持续运行的服务,我会结合搜索配额设置并发限制、单来源超时和失败状态,而不是只增加子查询数量。当前_process_sub_query会把常见异常记录后转换为空字符串,汇总时过滤空值,因此有报告产出也可能仍有部分研究问题没有资料。2. 获取正文、控制重复,再挑选相关上下文
每个子查询遍历已配置的检索器,获得待抓取链接或检索器已取回的正文。当前实现优先看检索器的
requires_scraping声明:明确需要抓取的结果,即使带长摘要也仍需获取网页;明确已提供内容的结果可以直接复用。未声明的旧检索器才沿用raw_content长度启发式,不能一概把搜索摘要当成已读正文。对需要抓取的 URL,
_get_new_urls检查共享的visited_urls,先加入集合,再交给抓取器。这能减少并发子查询重复抓同一链接,但它按 URL 字符串判断,不会自动识别不同地址的转载;预取正文分支也不能据此推定绝无重复。并且“已加入集合”早于抓取成功,不能把访问集合直接当作成功读取的证据清单。来源获取与 URL 去重源码。网页内容随后进入
ContextManager的select_context。它按配置选择相关片段,而不是必须先建向量库:auto在有TYPESAFE_API_KEY时选择Jev,否则使用关键词排序;也可显式选择embeddings或不过滤的none。进入上下文的文档保留来源 URL、标题与内容,方便报告引用。筛选是在控制相关性和上下文体积,不能代替对来源可信度、时效和矛盾事实的判断。3. 报告基于已收集内容写,证据不足要留下缺口
普通入口先调用
conduct_research(),再调用write_report()。报告生成器把研究问题、上下文、报告类型、格式、语言等组装成写作请求;上下文为空时会直接说明未取得来源材料。默认报告提示词要求重要论断、数字和引文带文内链接,并在末尾列出采用的来源。报告生成器源码。如果目标是可核验的研究报告,我会再保存“子问题、论断、原文片段、URL、发布时间、核验状态”的证据表,写作前检查关键问题的覆盖情况,对冲突或缺证据的部分定向补搜。以调研固态电池商业化进展为例,可分别查技术指标、试产与量产、企业公告和独立测试;同一新闻的多处转载不能算多个独立证据,“计划量产”也不能被整合成“已经量产”。这些证据表、补查与逐论断核验属于增强设计,当前默认提示词要求引用,并不等于程序已逐条验证引用能支持结论。
停止条件也应明确:关键问题已有足够证据,或达到轮数、时间、费用预算;停止时输出仍未解决的问题。验收则分别看子问题覆盖、引用是否支持结论、冲突是否交代,以及耗时和调用成本,不能仅以报告篇幅或 URL 数量判断质量。
4. 普通研究、详细研究和深度研究怎样选?
- 普通
research_report:围绕一份查询计划采集和筛选资料,再写报告,适合范围清楚的调研。 detailed_report:先做初步研究并规划子主题,再由DetailedReport逐个生成子主题报告,共享 URL 集合,并传入已有章节及相关已写内容,最后组装长报告;子主题的外层循环是串行的。deep:GPTResearcher.conduct_research单独分流到DeepResearchSkill,有广度、深度和并发配置,继续递归追查研究方向。multi_agents:后端转到另一套多代理入口,组织规划、研究、审阅与写作等协作;不能将它的角色和审阅步骤写成普通子查询链默认执行的步骤。
选型取决于问题是否需要层层追查或多轮审阅。先让普通路线的来源获取和报告引用可靠,再按任务需要增加深度与协作;更多搜索与更多代理都会增加费用、延迟和汇总难度。
参考资料
- 国内:Datawhale:第十四章 自动化深度研究智能体:参考规划、执行、报告三阶段与子任务保留来源的组织方法,解释研究问题怎样转化为可执行任务和最终报告。
- 国内:JavaGuide:上下文工程:参考动态证据筛选、原始引用保留与摘要丢失的处理,说明上下文选择为何要兼顾相关性、关键条件和回查入口。
- 国内:adongwanai:Agentic RAG / Deep Research 备战手册:参考显式搜索规划、独立来源交叉验证和关键矛盾保留,解释证据表与缺口补查的增强设计。
- 国内:ranxi2001:评估与全局观:参考检索质量与最终回答质量分开评估的方法,说明报告验收为何要检查覆盖、引用支持和失败归因。
- 国外:Assaf Elovic:How we built GPT Researcher:参考有限查询计划、异步采集与汇总写作的设计动机;本文具体调用顺序与模式划分依据所选版本源码,不采用旧文中的效果数字。
- 国外:Python:Running Tasks Concurrently:依据
gather的并发调度和结果汇总语义,说明子查询协程怎样共同执行,以及为何并发上限和失败策略需要另外设计。
- 普通
上下文压缩或摘要会丢失信息,如何让损失尽可能小?
展开收起
核心回答
GPT Researcher把研究任务拆成子问题,搜集网页后,为每个问题筛选写作上下文。当前这条链路的“压缩”主要是选取相关原文片段:保留片段能减少转述时的改写,但被筛掉的条件、反证和长页面尾部内容仍可能丢失。降低损失要同时检查两件事:哪些材料进入筛选器,哪些片段最终进入模型。保留原始网页及来源位置,针对研究结论核对事实、日期、否定条件和相反证据;不能只看输入缩短了多少,或用相关性分数证明证据已经完整。
选择策略与实际触发条件
子问题通过
select_context()统一选择上下文。CONTEXT_FILTER默认是auto:存在TYPESAFE_API_KEY时用Jev,否则用本地关键词筛选。内容总量小于COMPRESSION_THRESHOLD,且页数不超过调用的max_results时,直接保留页面内容;当前默认字符阈值为8000,普通子查询传入max_results=10。因此配置了某个筛选器,也不代表每次都会调用它。选择入口、普通子查询调用。几种策略保留内容的依据不同:
none:不做相关性筛选,将页面交给格式化器;但页面进入SearchAPIRetriever时仍受MAX_CONTENT_CHARS限制,默认每页最多50000个字符,所以不能把它当作绝对无损的原文备份。keyword:默认按约1000字符切块、重叠100字符,用BM25排序;在统一选择入口中,保留得分至少为最高分0.5倍的片段,最多25块。若所有片段都没有关键词匹配,退回取前面的片段,不代表已找到了回答证据。embeddings:对分块内容做向量相似度过滤,再按结果数量限制格式化输出。它能补充不同表达之间的匹配,但相似度高仍可能只是主题接近,不能单独证明片段足以回答问题。jev:为原文片段评估对问题的帮助程度,再按分数阈值和数量筛选。它仍可能遗漏低分但关键的例外、日期或反证,需要核对最终保留内容。
这些数值是所核版本的默认配置,不是适合所有研究任务的推荐值。页面长度限制、关键词分块与选择、向量筛选、Jev 筛选。
哪些信息需要额外保留
BM25依赖词项匹配,当前分词包含通用正则、英文停用词和轻量词形处理,没有专门的中文分词流程。企业别名、缩写和不同表述需要用中文研究样本验证;不能因一次未匹配,就断言原文没有相关内容。固定分块也可能把数字与单位、结论与适用条件拆开,重叠只能缓解,不能保证关系完整。例如研究某产品是否已经交付,“发布样机”的新闻可能高分命中,而“尚未交付”的说明、不同日期的修订或例外条件可能被排除。业务集成可以为同一实体分别保留支持材料和反证,并在命中片段缺上下文时补读相邻段落,再判断结论。按问题保留条件、例外与冲突材料。
原有
Document保留title、source,分块后仍可随正文输出,便于知道内容来自哪个网址。但标题和网址不足以恢复网页当时的版本,也不能证明引用支持结论。进一步完善时,应保存网页快照、发布时间、片段位置及选取策略;发现日期或限定条件缺失时,回读原文,不依靠报告摘要反推。来源元数据、正文与来源格式化。回退之后仍要检查材料
select_context()在Jev抛出JevError时回退关键词筛选,在向量筛选分支捕获普通异常后也回退关键词筛选。关键词路径自身的异常没有在这里统一兜底,Jev分支也并非捕获所有异常;正常返回空选择同样不等于一定触发回退。因此,不能承诺任何失败都能自动得到有效上下文。实际异常与回退范围。回退解决的是筛选方式不可用时怎样继续,材料是否充分还要按研究问题判断。若保留片段缺少关键日期或反证,可以补查来源、降低筛选强度或扩大受控阅读范围;若仍无依据,应保留不确定性。
怎样验证损失是否减小
固定同一组网页和研究问题,标注必须保留的事实、单位、日期、否定条件及反证,再比较不同策略进入模型的片段与最终报告。分别记录关键证据覆盖、条件遗漏、引用支持情况、实际输入
Token、筛选调用和耗时;none对照也要检查页面长度限制,避免把已被截断的材料误当完整基线。例如同时放入“样机发布”“暂未交付”和后续更新材料,检查报告是否区分不同时间与状态。根据漏掉的具体证据,再调整分块、阈值、实体别名或补读方式。这是可执行的对照验证设计,尚不能据此声称某种策略已经提高准确率或保证无损。
如何评估 RAG 回答的引用准确性与证据覆盖?
展开收起
核心回答
把报告拆成需要依据的事实断言,逐条检查“引用是否来自本次材料、引用内容是否支持该断言、重要结论是否都有证据”。网址能打开、主题相关、文末列有参考资料,都不足以证明引用准确。 还要区分检索是否找到证据、筛选是否保留证据,以及写作是否正确使用证据。
GPT Researcher普通研究链会搜集资料、筛选上下文,再生成报告。上下文保留Source、Title、Content;默认报告提示要求每个实质性论断、数字和引语有正文引用,不能使用未提供的来源。这为溯源提供了基础,但不是程序逐条验证了引用蕴含关系。上下文格式、报告引用提示。先保存能够复核的研究记录
评估一个报告,至少保存研究问题及时间范围、抓取正文、来源地址、筛选后上下文、最终报告,以及它们使用的配置。只保存报告和几个网址,网页更新后就难以确定模型当时看见了什么。抓取时间也不等于事件发生时间,二者需要分别处理。
当前
visited_urls主要帮助避免重复抓取:_get_new_urls()在实际抓取前就加入集合。它不能直接作为“成功获取且已支持结论”的来源清单;不同网址转载同一篇新闻,也不会因此变成多份独立证据。访问集合更新。用于评测的证据记录应补充正文快照、发布时间和原始出处,分别标注抓取失败、未选入上下文、已用于报告等情况。引用准确性怎样检查
先用规则检查引用格式、是否有对应的本次来源、能否定位正文;再核对正文与断言的关系。把“营收增长、市场排名第一、原因是某项政策”拆成独立事实,不能因为一段材料只支持营收,就把整句话都判为有依据。
语义检查至少区分支持、部分支持、不支持和矛盾。对于数字,核对单位、分母、统计范围和日期;对于因果关系,不能把“同时发生”扩写成“导致”;对于预测和建议,保留其性质,不能当作已经发生的事实。多份资料共同支撑一句话时,也要保留每份证据的作用。
可以按预先约定的断言粒度统计两项:
- 引用有效性: 检查引用是否对关联断言提供有效支持,并单列无关引用、来源错误和只支持部分信息的情况。
- 断言证据覆盖率: 需要证据的事实断言中,有多少获得了足够的引用支持。未加引用的事实也进入分母,不能靠少写引用提高分数。
ALCE 的引用质量评估分别考察断言获得引用支持,以及是否夹带无关引用;实际项目需要事先固定断言切分、联合支持和部分支持的判定规范。自动判定器也会漏判,数字、冲突来源和关键结论应保留人工复核,不能用模型给出的总体高分替代逐条依据。
还要检查遗漏了哪些关键事实
“写出来的内容都有来源”不等于回答完整。例如问题要求比较两家公司本年度的收入、成本和风险,报告只写了一家的收入,即使该数字引用完全正确,任务仍未覆盖。
为固定问题标注必须回答的事实及支持材料,分别检查它们是否进入原始抓取、筛选后上下文和最终报告。证据没抓到,要查检索;抓到了却被筛掉,要查上下文选择;材料仍在却写错或漏写,要查生成。百炼 RAG 诊断采用分阶段保留召回与回答结果的方式定位问题;OpenSearch 评测说明也将检索完整度、忠实性与回答完整性分开。
还应避免混淆两个分母:断言证据覆盖针对“报告写出的事实”,任务覆盖针对“问题要求回答的事实”。前者可以很高,后者仍可能很低。一般忠实性评估检查回答能否由所给上下文推出,并不自动检查每一条指定引用是否准确,也不证明原始来源本身真实。Ragas 的忠实性定义。
当前实现提供了什么,还需要补什么
普通报告生成器发现上下文为空时,会明确无法生成可靠的有来源报告;非空上下文仍可能不足以回答问题,不能把这条空值保护说成完整证据审核。无资料时的处理。
仓库还有将访问网址排序后附加到末尾的
add_references(),用于详细报告的拼装;普通报告写作主要依赖引用提示。这个辅助函数只拼接网址,不读取相应正文证明论断。其他多 Agent 模式的事实检查步骤,也不能直接归到普通链中。参考资料拼接。若要完善质量验收,应补上断言与证据的关联记录,并用同一批冻结材料比较筛选策略和报告结果:统计引用有效性、断言证据覆盖、任务事实覆盖,同时观察延迟和输入成本。加入错误年份、转载重复、相互冲突的数字、抓取失败和没有答案的样例,确认系统能说明缺口。这是改进与评测方案,不是当前项目已经取得的准确率。