name: research-agent-optimization description: 优化研究智能体,处理速率限制,提升API调用效率,修复网络搜索集成问题,改进流式用户体验,提供细粒度进度更新和来源归属。
研究智能体优化
范围
- 项目根目录:
/home/bender/classwork/Thesis - 后端:
backend/news_research_agent.py,backend/app/api/routes/research.py,backend/app/services/news_research.py - 前端:
frontend/app/search/page.tsx,frontend/lib/api.ts - 配置:
backend/app/core/config.py
问题陈述
- 速率限制:在研究和文章分析过程中,Gemini API 遇到 429 配额超限错误。
- 网络搜索:DuckDuckGo 工具集成存在命名问题(未正确初始化)。
- 进度不明确:研究流式传输显示通用的“仍在工作…”而不是具体的工具调用信息。
- 响应中的JSON:结果显示原始JSON块而非格式化的来源卡片。
- 冗余的API调用:多个内部搜索调用没有缓存/去重。
预期成果
- 优雅的速率限制处理,包含指数退避和配额监控。
- 正常工作的网络搜索工具,正确初始化 DuckDuckGo。
- 详细的流式事件,显示真实的工具执行情况(web_search, news_search, internal_news_search)。
- 研究结果以内联来源卡片形式呈现(非JSON块)。
- 优化的API调用:批量搜索、缓存语义结果、重用内部知识库。
- 配额超限时显示清晰的错误信息。
工作流程
1. API调用优化
- 在
search_internal_news工具中实现请求批处理。 - 为语义搜索结果添加缓存层(避免在5分钟窗口内重复查询)。
- 将 web_search 和 news_search 合并到单个结果集中。
- 跟踪每个会话的API调用次数,并在配额耗尽前发出警告。
- 添加指数退避重试逻辑(最大1秒,2秒,4秒,8秒)。
文件:
backend/news_research_agent.py- 工具和缓存backend/app/services/news_research.py- 请求批处理助手
2. 速率限制与配额处理
- 在 Gemini 调用周围添加 try/catch 包装器。
- 检测 429 错误并返回用户友好的消息(“API速率限制:…请稍等片刻…”)。
- 当配额较低时,为文章分析添加可选的
--skip-gemini-analysis模式。 - 记录配额使用情况和剩余令牌数。
- 将模型设置为
gemini-2.0-flash(更快,令牌成本更低)而非gemini-2.0-flash-exp。
文件:
backend/app/core/config.py- 错误处理包装器,模型选择backend/app/api/routes/research.py- HTTP错误响应backend/news_research_agent.py- LLM调用错误处理
3. 网络搜索工具修复
- 验证 DuckDuckGo 导入:
from duckduckgo_search import DDGS(不是ddgs或DuckDuckGo)。 - 确保
web_search和news_search工具正确绑定到 LLM。 - 如果网络搜索失败,添加回退到内部搜索的机制。
- 记录工具执行情况,包括查询和结果数量。
文件:
backend/news_research_agent.py- 工具定义和错误处理- 使用
exa-code验证当前的 DuckDuckGo API 模式
4. 流式进度清晰化
- 扩展 SSE 事件类型:
tool_start包含工具名称 + 查询参数。 - 将工具事件映射到用户友好的消息:
web_search("climate change")→ “正在网络上搜索:climate change…”news_search(keywords="COP30")→ “正在搜索新闻:COP30…”search_internal_news(query)→ “正在搜索内部知识库…”fetch_article_content(url)→ “正在阅读文章:[标题/域名]…”
- 添加时间戳和工具执行时长。
- 如果没有工具活动,每 3-5 秒发出一次状态更新。
文件:
backend/news_research_agent.py- 流式生成器backend/app/api/routes/research.py- SSE 格式化
5. 前端结果渲染
- 从响应文本中移除 JSON 块。
- 在答案下方以“来源”部分渲染引用的文章。
- 使用文章卡片:标题、来源、日期、图片缩略图。
- 使卡片可点击以打开文章详情模态框。
- 按检索方法(语义、网络搜索、内部)对来源进行分组。
文件:
frontend/app/search/page.tsx- 消息渲染和来源网格frontend/lib/api.ts- 响应解析
6. 错误处理与用户反馈
- 检测并处理:
- 429 配额超限 → “API速率限制:AI服务已达到其速率限制。请稍等片刻再试。”
- 连接超时 → “请求超时:研究耗时过长。请尝试更简单的查询。”
- 工具执行失败 → “工具 [名称] 失败:[原因]。正在使用替代搜索继续…”
- 出错时添加重试提示(非自动,用户选择)。
- 记录所有错误及请求ID以便调试。
文件:
backend/app/api/routes/research.py- 错误格式化frontend/app/search/page.tsx- 错误UI和重试逻辑
检查项
API优化
- 验证语义搜索结果已缓存(无重复调用)。
- 检查 web_search 和 news_search 返回结果(非空)。
- 确认工具执行日志显示重复查询的缓存命中。
速率限制处理
- 触发 429 错误并验证优雅的回退消息是否显示。
- 确认未向用户显示堆栈跟踪。
- 检查日志是否显示配额状态和重试时间。
网络搜索
- 查询“climate change”并验证 web_search 返回 5+ 个结果。
- 确认 DuckDuckGo DDGS 类已正确实例化。
- 检查 news_search 返回最近的新闻文章。
流式清晰度
- 监控 SSE 事件中是否包含查询详情的 tool_start。
- 验证时间戳是否正确递增。
- 确认“仍在工作…”消息仅在 30 秒无活动后显示。
前端渲染
- 验证研究答案是纯文本(无JSON)。
- 检查“来源”部分是否出现文章卡片。
- 确认卡片点击打开文章详情模态框。
- 验证无重复来源(去重工作正常)。
错误场景
- 提交无效查询并验证不会崩溃。
- 测试网络断开连接并检查超时消息。
- 模拟配额超限(403)并验证用户看到速率限制消息。
实施清单
- [ ] 向 Gemini 客户端添加带有指数退避的重试装饰器。
- [ ] 在
search_internal_news中实现请求缓存,TTL为5分钟。 - [ ] 修复 DuckDuckGo 工具初始化(验证 DDGS 导入)。
- [ ] 更新
research_stream()以发出细粒度的工具开始/结果事件。 - [ ] 在API端点中将工具事件映射到人类可读的状态消息。
- [ ] 从最终答案文本中移除 JSON 块。
- [ ] 向前端添加带有文章卡片的“来源”部分。
- [ ] 更新针对 429 配额超限的错误处理。
- [ ] 向UI添加流式状态动画。
- [ ] 为配额处理和网络搜索集成编写测试。