- 使用
/augment/search搜索实时网络 - 决定其中哪些结果值得阅读
- 使用
/augment/scrape将选中的页面转换为 Markdown - 让聊天模型撰写简报,并按编号引用来源
- 将四个阶段串联成一个脚本
venice_parameters.enable_web_search。网页搜索与抓取 指南对这两种方式做了对比。
环境准备
你需要 Python 3.9 或更新版本、requests 包,以及一个 Venice API 密钥。如果还没有密钥,请参阅 生成 API 密钥。
research.py,先写入导入语句以及每次调用都会复用的共享请求头:
1. 搜索网络
/augment/search 接收一个查询,最多返回 20 条排序后的结果。Brave 是默认的提供商,并采用零数据保留。Google 也可用,其查询会通过 Venice 代理,因此查询永远不会与你关联。
content 字段返回时会带有 HTML,因为提供商会用 <strong> 标签包裹匹配到的词语。上面的 HTML_TAG 替换会将其剥离,使摘要以纯文本形式传给模型。
date 字段经常是空字符串。许多页面没有发布机器可读的日期,因此请将 date 视为一个仅在存在时可以参考的提示,而不是可以用来排序或过滤的字段。
2. 选择要阅读的来源
抓取全部十条结果既慢又昂贵,而且大多重复。搜索引擎经常返回同一站点的多个页面,尤其是文档站点会以多种语言返回同一页面,因此相同内容可能会以不同 URL 出现三到四次。 只保留每个域名中排名最高的一条结果,几行代码就能消除大部分重复:date 的结果。你在这里加的每一层过滤,都是模型没有机会出错的一个决策。
3. 抓取选定的页面
/augment/scrape 会获取一个公开 URL 并以 Markdown 返回。它会先向站点请求原生的 Markdown 版本,如果没有则回退到基于浏览器的提取方式。
有些页面会失败,研究工具应把这视为常态而非致命错误:
200 但只给回一个 cookie 提示或空壳而非文章的页面。
抓取失败会返回一个简单的
{"error": "..."} 响应体,包含可读的信息,例如 X (formerly Twitter) blocks automated access to their content.。X 和 Reddit 被完全屏蔽。如需在回答中包含 X 上的帖子,请在聊天补全上使用 venice_parameters.enable_x_search。4. 撰写简报
现在我们把收集到的页面按编号交给模型,并要求它使用这些编号进行引用。提示词中的编号让我们能够将输出中的[2] 追溯回 URL。
temperature 会让措辞更贴近原文。将 enable_web_search 设为 off 与默认行为一致,但明确写出来可以确保模型不会悄悄引入不在我们参考列表中的来源。
5. 把它们串联起来
最后一部分按顺序执行各阶段,并附上用于解析引用编号的参考列表:stderr,因此你可以将简报本身重定向到文件:
调整流水线
大部分实际耗时都花在最后一次聊天补全上,因为四个抓取到的页面加起来有数万个 token。以下是首先值得尝试的调节点:后续步骤
你现在得到的这套流水线是一个基础,而非成品。以下是几个值得探索的方向:- 按 URL 缓存抓取到的 Markdown,这样重复的问题就不会再次拉取同样的页面。
- 使用 嵌入 将 Markdown 存为向量,从而检索段落而非整页。
- 让模型先规划多个查询再进行搜索,就像 私密研究 Agent 示例那样。
- 通过将简报接入 使用文本转语音朗读文章 来朗读出简报内容。
网页搜索与抓取
Search 和 Scrape 端点的参考文档。
使用文本转语音朗读文章
将你刚生成的文本转换为音频。
嵌入
对抓取到的 Markdown 建立索引,而不是反复获取。
私密研究 Agent
一个能自行规划搜索的更完整 agent。