技术调研 · 工具实现报告

Jina AI × DeepAgents
网络搜索工具 & 文章撰写子 Agent

基于 Jina AI 三个 API(Search / Reader / DeepSearch)实现 deepagents 兼容的工具集与 文章撰写子 Agent,支持语义搜索、全文提取与深度研究流式输出。

s.jina.ai — 网络搜索
r.jina.ai — URL 阅读器
deepsearch.jina.ai — 深度研究
jina-writer SubAgent
目录
1
Jina AI API 概览与对比
API端点核心功能适用场景响应时间Token 计费
Search s.jina.ai Web 搜索,返回 top-N 页面内容(Markdown) 关键词/语义检索,找主要来源 ~2.5 s 固定 ≥10,000 tokens/次
Reader r.jina.ai 任意 URL → 清洁 Markdown 全文 深读特定文章、提取结构化内容 ~2-5 s 按输出 token 计
DeepSearch deepsearch.jina.ai 自主规划搜索策略、多源综合推理、带引用输出 长文写作、复杂研究、多步推理 30 s – 3 min 按全过程 prompt+completion
🔍 Search API 要点
  • POST {"q": "query"}
  • 支持 numglhl 参数
  • 返回 JSON 数组:title / url / content
  • 需要 API Key(免费 100 RPM)
  • Header: X-Return-Format: markdown
📖 Reader API 要点
  • GET r.jina.ai/{url}
  • 支持流式:Accept: text/event-stream
  • 支持 CSS selector 精准提取
  • 返回 JSON:title / content / links
  • ReaderLM-v2 引擎提升转换质量
🔬 DeepSearch API 要点
  • OpenAI Chat API 兼容格式
  • 模型名:jina-deepsearch-v1
  • SSE 流式强烈推荐(避免超时)
  • 响应含 <think> 推理块 + 正文 + annotations
  • team_size 支持多 agent 并行研究
2
Tool 1 — jina_search
POST https://s.jina.ai/

关键设计决策

每条结果截断 2000 字符
Search API 固定消耗 ≥10,000 tokens/次,但每条结果可能很长。 截断到 2000 字符保证 5 条结果总量在 10K tokens 以内,防止 context 溢出。
X-Return-Format: markdown
指定返回 Markdown 格式,LLM 直接可读,避免 HTML 标签噪音, 与 jina_reader 输出格式统一。
实现代码
@tool
def jina_search(
    query: Annotated[str, "Search query — describe what you want to find"],
    num_results: Annotated[int, "Number of results (1-10, default 5)"] = 5,
) -> str:
    """Search the web using Jina AI (s.jina.ai).
    Returns top results as LLM-friendly markdown with title, URL, and content.
    Use for: current events, factual lookup, finding primary sources.
    """
    headers = {
        "Authorization": f"Bearer {JINA_API_KEY}",
        "Accept":         "application/json",
        "X-With-Links-Summary": "true",
        "X-Return-Format":      "markdown",
    }
    payload = {"q": query, "num": max(1, min(10, num_results))}

    resp = requests.post(_SEARCH_URL, headers=headers, json=payload, timeout=30)
    resp.raise_for_status()
    items = resp.json().get("data", [])

    parts = []
    for i, item in enumerate(items, 1):
        content = (item.get("content") or "").strip()
        content = content[:2000] + ("…" if len(content) > 2000 else "")
        parts.append(f"[{i}] **{item.get('title')}**\nURL: {item.get('url')}\n\n{content}")

    return "\n\n---\n\n".join(parts) if parts else "No results found."
参数类型说明推荐值
querystr搜索词,支持自然语言用完整句子提升语义匹配
num_resultsint返回结果数,影响延迟3-5(综合质量与速度)
X-Return-Formatheader返回格式markdown
X-With-Links-Summaryheader提取页面链接true
3
Tool 2 — jina_reader
GET https://r.jina.ai/{url}

与 jina_search 的配合模式

典型用法:先用 jina_search 找到候选 URL,再用 jina_reader 精读最相关的 1-2 篇,获取完整内容。

实现代码
@tool
def jina_reader(
    url: Annotated[str, "Full URL to read (must start with http/https)"],
    max_chars: Annotated[int, "Max chars to return (default 6000)"] = 6000,
) -> str:
    """Read and extract clean Markdown from a URL using Jina AI (r.jina.ai).
    Use for: reading a specific article in full; following up on search results.
    """
    if not url.startswith("http"):
        return "[jina_reader error] URL must start with http:// or https://"

    headers = {
        "Authorization": f"Bearer {JINA_API_KEY}",
        "Accept":          "application/json",
        "X-Return-Format": "markdown",
    }
    resp = requests.get(f"{_READER_URL}{url}", headers=headers, timeout=30)
    resp.raise_for_status()

    payload = resp.json().get("data", {})
    title   = payload.get("title", url)
    content = (payload.get("content") or "").strip()

    truncated = content[:max_chars] + ("…[truncated]" if len(content) > max_chars else "")
    return f"# {title}\nSource: {url}\n\n{truncated}"
max_chars 参数的重要性
单篇文章可能超过 50,000 字符。默认截断到 6,000 字符(约 1,500 tokens)平衡完整性与上下文占用。 对于需要完整内容的场景(如法律文件、技术规范),可设置到 20,000+。
4
Tool 3 — jina_deepsearch(流式 SSE)
POST https://deepsearch.jina.ai/v1/chat/completions

流式处理架构

DeepSearch 响应时间长达 3 分钟,必须使用 SSE 流式接收,否则会触发 524 超时。

客户端 (jina_deepsearch tool) DeepSearch API │ │ │── POST /v1/chat/completions (stream=true) ──▶│ │ │ │◀── data: {"delta":{"content":"<think>..."}} ─│ 推理块 │◀── data: {"delta":{"content":"..."}} ─────── │ 搜索中... │◀── data: {"delta":{"content":"..."}} ─────── │ 阅读中... │◀── data: {"delta":{"content":"## 正文..."}} │ 开始输出 │◀── data: {"delta":{"annotations":[...]}} ── │ inline citations │◀── data: [DONE] ──────────────────────────── │ │ │ ├─ strip <think>...</think> │ ├─ dedupe citations │ └─ append Sources section → return str │

SSE 解析核心逻辑

with requests.post(_DEEPSEARCH_URL, headers=headers, json=payload,
                    stream=True, timeout=300) as resp:
    for raw_line in resp.iter_lines():
        line = raw_line.decode("utf-8") if isinstance(raw_line, bytes) else raw_line
        if not line.startswith("data: "): continue

        data_str = line[6:].strip()
        if data_str == "[DONE]": break

        chunk  = json.loads(data_str)
        delta  = chunk["choices"][0]["delta"]

        # 1. 累积正文(含 <think> 推理块)
        full_content += delta.get("content") or ""

        # 2. 收集 inline citations
        for ann in delta.get("annotations") or []:
            if ann.get("type") == "url_citation":
                citations.append(ann.get("url_citation", {}))

# 后处理
answer = _strip_thinking(full_content)   # 移除 <think>...</think>
answer += _format_sources(citations)     # 去重 + 追加 Sources 节

请求参数说明

参数类型说明推荐配置
reasoning_effortstr研究深度控制low 快速验证 / medium 日常 / high 长文章
no_direct_answerbool强制执行 Web 搜索(不从记忆直接回答)true(保证时效性)
budget_tokensint全过程 token 上限不设则用默认,高成本场景可限制
team_sizeint并行研究 agent 数量默认 1;复杂多角度研究可设 2-3
boost_hostnameslist优先抓取的域名可指向高质量来源
streambool流式输出始终设为 true
响应结构:<think> 推理块 vs 最终正文
DeepSearch 返回的内容包含两部分:
<think>…搜索规划、中间推理…</think> + 最终文章正文。
实现中用 re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL) 剥离推理块, 仅保留最终输出,显著减少返回给主 agent 的 token 量。
5
SubAgent — jina-writer

jina-writer 是一个 deepagents 兼容的文章撰写子 agent, 持有全部三个 Jina 工具,系统提示指导其完成"理解需求 → 深度研究 → 撰写文章"的完整流程。

SubAgent 定义
jina_writer_subagent = {
    "name": "jina-writer",
    "description": (
        "Writes comprehensive, citation-backed articles and research reports "
        "using Jina AI DeepSearch for up-to-date web research. "
        "Use for: long-form articles, market research, topic overviews, "
        "technical summaries requiring current sources. "
        "Pass: article topic, desired length/sections, target audience."
    ),
    "system_prompt": JINA_WRITER_INSTRUCTIONS,   # 见下方
    "tools": [jina_deepsearch, jina_search, jina_reader],
    # "model": "anthropic:claude-haiku-4-5-20251001",  # 可选降本
}

JINA_WRITER_INSTRUCTIONS 结构

## Role
Given a writing request, you:
1. Research the topic thoroughly using jina_deepsearch
2. Optionally deepen specific angles with jina_search + jina_reader
3. Synthesize all findings into a well-structured, citation-backed piece

## Tools Available
- jina_deepsearch(query, reasoning_effort)  ← primary: deep research
- jina_search(query, num_results)           ← supplement: targeted search
- jina_reader(url)                          ← supplement: read specific source

## Writing Process
Step 1: Understand scope, sections, audience, tone
Step 2: Call jina_deepsearch (high for >1000 words, medium for standard)
Step 3: jina_search + jina_reader for sub-topic depth if needed
Step 4: Write article — synthesize, do NOT dump raw DeepSearch output

## Output Structure (Markdown)
# [Title]
## Introduction / Executive Summary
## [Section 1…N]  ← with inline citations [1][2]
## Conclusion
## References
[1] Title — URL
...

## Constraints
- Every fact must carry [x] citation
- Consolidate all URLs in References
- No fabrication — only cite tool-returned sources
关键设计:subagent 写完整文章,而非证据包
与 KB Agent 中的 research-agent(返回证据包,主 agent 合成报告)不同, jina-writer 直接返回完整 Markdown 文章。 因为 DeepSearch 本身已完成综合推理,subagent 直接产出成品效率更高; KB Agent 的主 agent 只需将文章嵌入对话输出,无需再次合成。
6
与 KB Agent 的集成

jina-writer 作为 KB Agent 的新增 subagent, 主要接管 Section F(报告写作)中需要引用最新网络信息的场景, 与现有 research-agent(KB 内部证据采集)形成互补。

两个写作 subagent 的分工

SubAgent数据来源适用场景输出
research-agent 内部知识库(retrieve_from_kb, get_doc_context_by_id) 基于已上传文件的尽调报告、内部分析 Evidence Package(证据包)
jina-writer 实时网络(Jina Search + DeepSearch) 行业报告、市场分析、需要最新信息的文章 完整 Markdown 文章

Section F 路由扩展

### F. Report Writing and Structured Analysis
...
  1. Pre-collect context: retrieve_from_kb + list_business_contexts
  2. Route by evidence availability:
     - KB evidence sufficient → task(subagent_type="research-agent")
       # 返回 Evidence Package,主 agent 合成报告
     - Needs current web data → task(subagent_type="jina-writer")
       # 返回完整文章,主 agent 直接整合或转述
     - Both needed → sequential: research-agent first, then jina-writer
       # 内部 KB 证据 + 网络信息双来源合并

集成代码

from jina_tools import (
    jina_search, jina_reader, jina_deepsearch,
    jina_writer_subagent,
)

agent = create_deep_agent(
    model=init_chat_model("anthropic:claude-sonnet-4-6", temperature=0.0),
    tools=[
        retrieve_from_kb,
        list_business_contexts,
        get_doc_context_by_id,
        think_tool,
        jina_search,    # ← 新增:主 agent 也可直接搜索
        jina_reader,    # ← 新增:主 agent 可读取指定 URL
    ],
    system_prompt=KB_WORKFLOW_INSTRUCTIONS_RESEARCH,
    subagents=[
        research_sub_agent,     # KB 内部证据采集
        jina_writer_subagent,   # ← 新增:网络研究 + 文章撰写
        mermaid_expert_subagent,
        file_catalog_subagent,
    ],
)
7
完整运行时架构
┌───────────────────────────────────────────────────────────────────┐ │ KB Agent(主 agent) │ │ tools: retrieve_from_kb · jina_search · jina_reader · ... │ └──────┬───────────────┬──────────────────┬───────────────────────── ┘ │ │ │ task("research-agent") task("jina-writer") task("file_catalog") │ │ │ ┌──────▼──────┐ ┌────────▼──────────┐ ┌───▼──────────────┐ │research- │ │ jina-writer │ │ file_catalog │ │agent │ │ SubAgent │ │ SubAgent │ │ │ │ │ │ │ │tools: │ │tools: │ │(已有,不变) │ │ retrieve_ │ │ jina_deepsearch │ │ │ │ from_kb │ │ jina_search │ └──────────────────┘ │ list_biz_ │ │ jina_reader │ │ contexts │ │ │ │ get_doc_ │ │ ┌─────────────┐ │ │ context │ │ │jina_deep- │ │ │↩ Evidence │ │ │search tool │ │ │ Package │ │ │ ↕ SSE │ │ │ │ │ │deepsearch │ │ │ │ │ │.jina.ai │ │ │ │ │ └─────────────┘ │ │ │ │↩ 完整 Markdown │ │ │ │ 文章 + 引用 │ └─────────────┘ └───────────────────┘
8
配置与成本参考

环境变量

# .env
JINA_API_KEY=jina_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   # 从 jina.ai 获取

# 获取免费 API Key(10M tokens 免费额度)
# https://jina.ai/?sui=apikey

成本与速度权衡

场景推荐工具reasoning_effort预估耗时Token 消耗
快速事实核查jina_search~3s固定 ≥10K
读取特定页面jina_reader~3s按输出量
500字简短报告jina_deepsearchlow~30s~30K
1500字标准文章jina_deepsearchmedium~60s~80K
3000字深度报告jina_deepsearchhigh~3min~200K
⚠️ DeepSearch 超时风险
high 模式耗时可能超过 3 分钟。实现中设置 timeout=300(5分钟上限)。 若集成到 LangGraph,需确保 step timeout 配置足够宽松。
💡 Rate Limits
Search: 100 RPM(免费)/ 1000 RPM(Premium)
Reader: 500 RPM(标准)/ 5000 RPM(Premium)
DeepSearch: 50 RPM(所有层级)
生产环境建议申请 Premium Key。

文件清单

文件内容
jina_tools.py三个 LangChain @tool + jina_writer_subagent 定义 + 测试入口
kb_agent_integrated.pyKB Agent 完整集成代码(含 research-agent + jina-writer)
基于 jina.ai API 文档分析 · langchain-ai/deepagents · 报告生成:2026-04-20