> ## Documentation Index
> Fetch the complete documentation index at: https://docs.llmquantdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 论文搜索

> 在 LLMQuant Quant Paper 语料上做语义检索 —— 先定位论文，再按需加载具体章节。

<Note icon="sparkles">
  **已暴露为 MCP 工具**：`paper_search` + `paper_read` —— 在 Claude / Cursor / 任意 MCP 客户端中直接调用。详见 [MCP Server](/zh-CN/integration/mcp-server) 60 秒配置。
</Note>

<Badge color="green" icon="circle-check">已上线</Badge>
 
<Badge color="blue" size="sm">1 credit · search</Badge>
 
<Badge color="gray" size="sm">免费 · read</Badge>

## 它为 Agent 做什么

`paper_search` 接收自然语言查询，返回 Quant Paper 中最相关的 knowledge card —— 因子、异象、市场微结构、ML for finance 等研究。它是 agent 的 **文献入口**：当 agent 要把一个判断锚到学术文献上（"momentum crash 真的存在吗？"、"factor zoo 那篇到底说了什么？"），先调 `paper_search` 拿到候选 `paperCardId` + `availableSections`，再用 `paper_read` 加载真正需要的章节。

向量基于 `title + abstract + summary + tags`，所以 card 级命中是"值得继续 `paper_read`"的信号 —— `paper_search` 故意**不**返回正文。

## Agent flow

```mermaid theme={null}
sequenceDiagram
  participant Agent
  participant MCP as data-mcp
  Agent->>MCP: paper_search(query, topK=5)
  MCP-->>Agent: items[] · paperCardId · summary · availableSections
  Note over Agent: 扫描 summary + section manifest
  alt summary 已经够用
    Agent->>Agent: 用 summary + tags 直接回答
  else 需要特定章节
    Agent->>MCP: paper_read(paperCardId, sections=[keys])
    MCP-->>Agent: sections[].content (Markdown)
  else 需要全文
    Agent->>MCP: paper_read(paperCardId, sections=["all"])
    MCP-->>Agent: 按 order 返回完整 sections[]
  end
```

## 返回值

### `paper_search` 返回

<ResponseField name="data" type="PaperCard[]" required>
  按相关性降序排列的论文卡片数组。

  <Expandable title="PaperCard 字段">
    <ResponseField name="paperCardId" type="string" required>
      稳定标识符。传给 `paper_read` 加载具体章节内容。
    </ResponseField>

    <ResponseField name="sourcePaperId" type="string" required>
      原始来源标识（如 arXiv ID）。
    </ResponseField>

    <ResponseField name="title" type="string" required>
      论文标题。
    </ResponseField>

    <ResponseField name="authors" type="string[]" required>
      作者列表。
    </ResponseField>

    <ResponseField name="abstract" type="string" required>
      论文原始 abstract。
    </ResponseField>

    <ResponseField name="summary" type="string" required>
      LLM 生成的 2–3 句摘要。**用它判断是否值得花一次 `paper_read` 加载完整章节**。
    </ResponseField>

    <ResponseField name="tags" type="string[]" required>
      研究主题标签（如 `factor`、`momentum`、`deep-learning`）。
    </ResponseField>

    <ResponseField name="availableSections" type="object[]" required>
      章节 manifest。每条含 `section_key`、`section_type`、`title`、`char_count`、`section_order`。调 `paper_read` 时使用其中的 `section_key`。
    </ResponseField>

    <ResponseField name="sectionCount" type="number" required>
      可用章节总数。
    </ResponseField>

    <ResponseField name="fullTextCharCount" type="number" required>
      所有章节合计字符数。
    </ResponseField>

    <ResponseField name="pdfUrl" type="string" required>
      论文 PDF 直链。
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta.creditsUsed" type="number">本次调用消耗的 credit（搜索固定 `1`）。</ResponseField>
<ResponseField name="meta.remainingCredits" type="number">账户剩余 credit。</ResponseField>

```json title="200 OK · paper_search" expandable theme={null}
{
  "data": [
    {
      "paperCardId": "card_abc123",
      "sourcePaperId": "arxiv:1404.4944",
      "title": "Momentum Crashes",
      "authors": ["Kent Daniel", "Tobias J. Moskowitz"],
      "abstract": "Despite their strong positive abnormal returns, momentum strategies experience infrequent but severe crashes...",
      "summary": "记录了动量组合在熊市反弹之后出现的剧烈崩溃，并给出可在实时操作中识别的 market-state / volatility 预测变量。",
      "tags": ["factor", "momentum", "crash"],
      "availableSections": [
        { "section_key": "introduction", "section_type": "introduction", "title": "Introduction", "char_count": 18420, "section_order": 1 },
        { "section_key": "methodology", "section_type": "method", "title": "Methodology", "char_count": 22150, "section_order": 2 }
      ],
      "sectionCount": 6,
      "fullTextCharCount": 102345,
      "pdfUrl": "https://arxiv.org/pdf/1404.4944"
    }
  ],
  "meta": { "creditsUsed": 1, "remainingCredits": 99 }
}
```

### `paper_read` 返回

<ResponseField name="data" type="PaperReadResult" required>
  单篇 paper 的指定章节集合。

  <Expandable title="PaperReadResult 字段">
    <ResponseField name="paperCardId" type="string" required>稳定标识符。</ResponseField>
    <ResponseField name="sourcePaperId" type="string" required>原始来源标识。</ResponseField>
    <ResponseField name="title" type="string" required>论文标题。</ResponseField>
    <ResponseField name="authors" type="string[]" required>作者列表。</ResponseField>
    <ResponseField name="abstract" type="string" required>原始 abstract。</ResponseField>
    <ResponseField name="summary" type="string" required>LLM 摘要。</ResponseField>
    <ResponseField name="tags" type="string[]" required>主题标签。</ResponseField>
    <ResponseField name="pdfUrl" type="string" required>论文 PDF 直链。</ResponseField>

    <ResponseField name="availableSections" type="object[]" required>
      章节 manifest（与 `paper_search` 中结构相同）。
    </ResponseField>

    <ResponseField name="sectionCount" type="number" required>可用章节总数。</ResponseField>
    <ResponseField name="fullTextCharCount" type="number" required>所有章节合计字符数。</ResponseField>

    <ResponseField name="sections" type="object[]" required>
      请求到的章节内容，按 `section_order` 排列。每条含 `section_key`、`section_type`、`title`、`content`（Markdown）、`char_count`、`section_order`。
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta.creditsUsed" type="number">读取固定 `0`。</ResponseField>
<ResponseField name="meta.remainingCredits" type="number">账户剩余 credit。</ResponseField>

## 说明

<Tip>
  **两步检索是 canonical 模式**：`paper_search` 用 1 credit 拿一组 ID + summary + section manifest，agent 据此判断要不要加载章节；再用 `paper_read` 免费加载真正需要的章节。建议先读 top-1 的 `introduction` + `methodology`；要核对具体结论时再加章节。
</Tip>

<Tip>
  调 `paper_read` **之前**就用 `paper_search` 返回的 `availableSections[i].char_count` 决定读哪几节。长文不要随手 `["all"]` —— 精准加载 1–2 节，agent context 会小很多。
</Tip>

<Warning>
  超过 **2,000 字符** 的查询会返回 `400`。把 agent 上下文里的长文先做摘要再调用。
</Warning>

<Warning>
  `paper_search` 的 `topK` 上限是 **10**，超出会被静默截断。
</Warning>

<Warning>
  `paper_search` **只返回 card 级元数据**，不带正文。要拿到章节内容必须调 `paper_read`。
</Warning>

## 直接调用

<Accordion title="HTTP / SDK 示例" icon="terminal">
  <CodeGroup>
    ```typescript MCP (Claude / Cursor) theme={null}
    // 1) 搜索
    {
      "method": "tools/call",
      "params": {
        "name": "paper_search",
        "arguments": { "query": "momentum crash", "topK": 5 }
      }
    }

    // 2) 读 top hit 的指定章节
    {
      "method": "tools/call",
      "params": {
        "name": "paper_read",
        "arguments": {
          "paperCardId": "card_abc123",
          "sections": ["introduction", "methodology"]
        }
      }
    }
    ```

    ```python Python (HTTP) theme={null}
    import os, requests

    base = "https://api.llmquantdata.com"
    headers = {
        "Authorization": f"Bearer {os.environ['LLMQUANT_API_KEY']}",
        "Content-Type": "application/json",
    }

    # 1) 搜索
    hits = requests.post(
        f"{base}/api/paper/search",
        headers=headers,
        json={"query": "momentum crash", "topK": 5},
    ).json()["data"]

    # 2) 读 top hit 的指定章节
    top = hits[0]
    paper = requests.post(
        f"{base}/api/paper/read",
        headers=headers,
        json={
            "paperCardId": top["paperCardId"],
            "sections": ["introduction", "methodology"],
        },
    ).json()["data"]

    for section in paper["sections"]:
        print(f"## {section['title']} ({section['char_count']} chars)")
        print(section["content"][:500])
    ```

    ```bash cURL theme={null}
    # 1) 搜索
    curl -X POST "https://api.llmquantdata.com/api/paper/search" \
      -H "Authorization: Bearer $LLMQUANT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query": "momentum crash", "topK": 5}'

    # 2) 读指定章节
    curl -X POST "https://api.llmquantdata.com/api/paper/read" \
      -H "Authorization: Bearer $LLMQUANT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"paperCardId": "card_abc123", "sections": ["introduction", "methodology"]}'
    ```
  </CodeGroup>
</Accordion>

## 完整参数参考

<AccordionGroup>
  <Accordion title="paper_search — 请求参数" icon="magnifying-glass">
    <ParamField body="query" type="string" required>
      自然语言查询字符串。最多 2,000 字符。
    </ParamField>

    <ParamField body="topK" type="number" default={5}>
      返回结果上限。范围 `1–10`。
    </ParamField>
  </Accordion>

  <Accordion title="paper_read — 请求参数" icon="book-open">
    <ParamField body="paperCardId" type="string" required>
      `paper_search` 返回的 `paperCardId`。
    </ParamField>

    <ParamField body="sections" type="string[]" default={["all"]}>
      章节 key 数组，取自 `availableSections[].section_key`。省略或传 `["all"]` 表示读全文。
    </ParamField>
  </Accordion>
</AccordionGroup>

## 相关接口

<Columns cols={2}>
  <Card title="Wiki 搜索" icon="book" href="/zh-CN/api/knowledge/wiki-search">
    同样的两步检索模式，作用在 Quant Wiki 语料（概念、公式、因子）上。
  </Card>

  <Card title="MCP Server 接入" icon="plug" href="/zh-CN/integration/mcp-server">
    60 秒接入 Claude / Cursor / 任意 agent harness。
  </Card>
</Columns>
