# 知识搜索 (/zh/features/ai/knowledge-search)

如何从数千个页面和消息中找到正确答案？VBT 的知识搜索让您从 Python 搜索文档、API
参考、代码示例和社区解答。可以查找一条准确的警告，也可以用自己的话提问，再打开原始来源。您还可以将最佳匹配项收集为自己大语言模型的上下文。

```python title="Search the knowledge base and see where the best matches come from"
>>> def source(link):
...     if "discord.com" in link:
...         return "community"
...     if "/api/" in link:
...         return "API"
...     if "/tutorials/" in link or "/cookbook/" in link:
...         return "tutorials and cookbook"
...     return "documentation"

>>> results = vbt.search("trailing stop after partial exit", display=False)  # (1)
>>> len(results)
42434
>>> top = results[:20]
>>> pd.Series([source(d["link"]) for d in top]).value_counts()
community        17
documentation     2
API               1
Name: count, dtype: int64
>>> docs = [d["link"].split(".pro")[1] for d in top if source(d["link"]) != "community"]
>>> print("\n".join(dict.fromkeys(docs)))
/documentation/portfolio/from-signals/#types
/documentation/portfolio/from-signals/#creation-1
/api/signals/generators/stcx/#vectorbtpro.signals.generators.stcx.STCX.exit_place_func_nb
```

1.  针对查询对全部 42,434 个文档进行排名，并按相关性从高到低返回。不设置 `display=False` 时，结果会作为 HTML 页面在浏览器中打开。

数据缓存后，在 Apple M3 上搜索整个知识库耗时 2.7 秒。首次搜索会下载知识资产及其预计算嵌入，此处耗时约 15 分钟。针对某个具体情形的问题，前 20
项中社区解答占大多数，同时也包括解释止损订单创建方式的文档章节。

## 知识库 \[#the-knowledge-base]

知识库由多类资产组成：网站页面、社区消息、代码示例和概念。每类资产都是一组包含链接、标题和内容的记录。`vbt.find_docs`、`vbt.find_api`、`vbt.find_examples`
和 `vbt.find_messages` 返回与对象或查询相关的记录。资产本身也可像数据一样通过 `select`、`query`、`find` 和 `apply`
等方法筛选、查询、排序、分组和合并。搜索前可以将消息讨论串和页面章节组合为单个文档，也可以将自己的文本封装为资产，以相同方式搜索或对话。请参阅下方[知识资产](#knowledge-assets)功能介绍。

## 搜索与排名 \[#search-and-ranking]

排名分为三个步骤：

*   **拆分：** 将长文档拆分成块，同时保留完整代码块和标题。
*   **检索：** 嵌入查找语义相近的文档，BM25 查找包含相同词语的文档，默认混合模式使用倒数排名融合合并两种排名。
*   **重排：** 可选的重排器使用 Cohere、Jina、Voyage、本地 Hugging Face
    交叉编码器或任意大语言模型，再次为靠前的结果评分，如下方[重排](#reranking)功能介绍所示。

嵌入可来自 OpenAI、Gemini、Voyage、Cohere、Jina、Hugging Face、本地 Sentence Transformers 模型或 Ollama，并存储在内存、文件或
LMDB 中。对于默认模型，知识库的预计算嵌入随每个版本一起下载，因此只需为查询生成嵌入。不同模型的嵌入不能混用，所以更换嵌入提供商后，请清除缓存嵌入，让 VBT 重新生成。

网站页面和社区消息不包含在软件包中。它们使用安装 VBT 时相同的 `GITHUB_TOKEN`，从 GitHub 发布版本下载；VBT
更新后，会在首次搜索时获取匹配的资产。没有访问权限的机器可以将资产设置指向这些文件的本地副本。

## 搜索工具 \[#search-tools]

| 工具                          | 用途                 | 需要什么                   |
| --------------------------- | ------------------ | ---------------------- |
| `vbt.search`                | 用自己的话提问，结合语义和关键词搜索 | 嵌入提供商                  |
| `vbt.quick_search`          | 查找准确警告、函数名称及其他关键词  | 除已下载资产外无需其他服务          |
| `vbt.chat`、`vbt.quick_chat` | 基于检索来源获得回答         | 补全提供商；`vbt.chat` 还需要嵌入 |

结果可作为 HTML 页面打开，或作为资产返回供您自己的代码使用，如下方 [SearchVBT](#searchvbt)
和[快速搜索与对话](#quick-search-and-chat)功能介绍所示。[AI 研究助手](/zh/features/ai/ai-research-assistant/)也使用同样的排名方式；会员网站还提供独立的页面和
API 搜索栏。

## 查找代码或社区解答 \[#find-code-or-community-answers]

正在寻找可运行的示例？使用 `asset_names="examples"` 限定搜索范围。需要排查警告或不常见的回测设置？使用 `asset_names="messages"`
搜索社区讨论。这样便能选择所需答案的类型，无需一次搜索所有来源。

如果已知 VBT 对象，`vbt.find_api` 和 `vbt.find_examples` 可以直接查找其 API
参考和示例。对于自定义信号逻辑，下方[知识资产](#knowledge-assets)示例进一步展示了如何查找包含特定函数定义的代码。

## 搜索自己的研究笔记 \[#search-your-own-research-notes]

知识库也可以包含您自己的资料。将笔记或从文档提取的文本封装为 `KnowledgeAsset`，然后筛选、搜索或围绕它进行对话。例如，将执行假设和验证计划保存在一起，并找到需要的笔记：

```python title="Find an execution assumption in personal research notes"
>>> notes = vbt.KnowledgeAsset([
...     dict(title="Execution assumptions", content="Compare slippage of 0.05% and 0.1%."),
...     dict(title="Validation plan", content="Reserve the final year for out-of-sample testing."),
... ])
>>> print(notes.find("slippage").get("title"))
['Execution assumptions']
```

此文本查找在本地运行，无需嵌入或对话提供商。如果希望就笔记提问，同一资产也可以为模型提供上下文。

## 为自己的大语言模型提供上下文 \[#context-for-your-own-llm]

`to_context` 在 token 预算内将排名结果转换为一段文本，可选附加链接等元数据，随时粘贴到任意模型或传入您自己的流程。通过 `max_tokens`
选择包含多少来源资料。本地缓存让下载的资产和搜索结果可重复使用，回答也可流式传输到 notebook，或保存为文本、Markdown 或 HTML。

## 重排 \[#reranking]

新增于 v2026.4.7

✅ 初步检索文档后，VBT 现在可以使用专门的重排模型对结果重新排序，突出最相关的文档。内置支持五类提供商：Cohere、Jina、Voyage、Hugging Face
交叉编码器（本地），以及通过补全评分的任意大语言模型。

=== "示例 1：使用重排搜索"
    ```python title="Rerank search results using Cohere"
    >>> env["COHERE_API_KEY"] = "<YOUR_COHERE_API_KEY>"

    >>> vbt.search(  # (1)
    ...     "How to rebalance weekly?",
    ...     rerank=True,  # (2)
    ...     reranker="cohere",  # (3)
    ...     rerank_limit=20,  # (4)
    ... )
    ```

    1.  对 `vbt.chat()`、`vbt.quick_chat()` 和 `vbt.interact()` 同样适用。
    2.  在初次检索后启用重排。
    3.  选择重排器。可选项：`"cohere"`、`"jina"`、`"voyage"`、`"hf_cross_encoder"`、`"completions"`。
    4.  仅将初始排名的前 20 个文档发送给重排器。

=== "示例 2：使用本地重排对话"
    ```python title="Rerank using a local cross-encoder model"
    >>> env["OPENAI_API_KEY"] = "<YOUR_OPENAI_API_KEY>"

    >>> vbt.chat(  # (1)
    ...     "How to use stop losses with from_signals?",
    ...     rank_kwargs=dict(
    ...         rerank=True,
    ...         reranker="hf_cross_encoder",  # (2)
    ...     ),
    ...     formatter="html",
    ... )
    ```

    1.  调用 `vbt.chat()` 时，通过 `rank_kwargs` 传入重排参数。
    2.  使用 Hugging Face 交叉编码器模型，在本地完全离线重排。

!!! info "实用示例"
    不使用 OpenAI？请在[实用示例](/zh/cookbook/)的知识部分探索更多配置。

## 快速搜索与对话 \[#quick-search-and-chat]

新增于 v2025.5.11

✅ 除了需要预先生成的嵌入外，VBT 现在还支持
[BM25](https://en.wikipedia.org/wiki/Okapi_BM25)，提供快速且完全离线的词法搜索。这非常适合快速查找具体内容。

```python title="Search VBT knowledge for a warning"
>>> env["GITHUB_TOKEN"] = "<YOUR_GITHUB_TOKEN>"

>>> vbt.quick_search("UserWarning: Symbols have mismatching index")
```

=== "第 1 页"
    ![](/assets/images/features/intelligence/quick_search1.light.png#only-light)
    ![](/assets/images/features/intelligence/quick_search1.dark.png#only-dark)

=== "第 2 页"
    ![](/assets/images/features/intelligence/quick_search2.light.png#only-light)
    ![](/assets/images/features/intelligence/quick_search2.dark.png#only-dark)

=== "第 3 页"
    ![](/assets/images/features/intelligence/quick_search3.light.png#only-light)
    ![](/assets/images/features/intelligence/quick_search3.dark.png#only-dark)

## SearchVBT \[#searchvbt]

新增于 v2025.3.1

✅ 想通过自然语言在网站或 Discord 上查找具体信息？SearchVBT 接收您的问题，生成包含排名结果及来源链接的 HTML 页面。它同时按语义和关键词搜索，因此即使尚不知道 VBT
函数名称，也能描述自己想做的事情。

```python title="Search VBT knowledge for a warning"
>>> env["GITHUB_TOKEN"] = "<YOUR_GITHUB_TOKEN>"
>>> env["OPENAI_API_KEY"] = "<YOUR_API_KEY>"

>>> vbt.search("How to run indicator expressions?")
```

=== "第 1 页"
    ![](/assets/images/features/intelligence/searchvbt1.light.png#only-light)
    ![](/assets/images/features/intelligence/searchvbt1.dark.png#only-dark)

=== "第 2 页"
    ![](/assets/images/features/intelligence/searchvbt2.light.png#only-light)
    ![](/assets/images/features/intelligence/searchvbt2.dark.png#only-dark)

=== "第 3 页"
    ![](/assets/images/features/intelligence/searchvbt3.light.png#only-light)
    ![](/assets/images/features/intelligence/searchvbt3.dark.png#only-dark)

## 知识资产 \[#knowledge-assets]

新增于 v2024.11.12

✅ 每个[发布版本](https://github.com/polakowo/vectorbt.pro/releases)现在都包含有价值的知识资产：内含私有网站内容和完整“vectorbt.pro”
Discord 历史的 JSON 文件。这些资产可用于大语言模型和 Cursor 等服务。此外，VBT 提供多种处理这些资产的类，支持转换为 Markdown 和 HTML
文件、离线浏览网站、定向搜索、与大语言模型交互等功能！

```python title="Gather all pages and messages that define signal_func_nb"
>>> env["GITHUB_TOKEN"] = "<YOUR_GITHUB_TOKEN>"

>>> pages_asset = vbt.PagesAsset.pull()  # (1)
>>> messages_asset = vbt.MessagesAsset.pull()
>>> vbt_asset = pages_asset + messages_asset
>>> code = vbt_asset.find_code("def signal_func_nb", return_type="item")
>>> code.print_sample(seed=42)  # (2)
```

1.  首次拉取会下载资产，后续拉取则使用缓存版本。
2.  打印一段随机代码片段。

````yaml
link: https://discord.com/channels/x/918630948248125512/1251081573147742298
block: https://discord.com/channels/x/918630948248125512/1251081573147742298
thread: https://discord.com/channels/x/918630948248125512/1250844139952541837
reference: https://discord.com/channels/x/918630948248125512/1250844139952541837
replies:
- https://discord.com/channels/x/918630948248125512/1251083513336299610
channel: support
timestamp: '2024-06-14 07:51:31'
author: '@polakowo'
content: Something like this
mentions:
- '@fei'
attachments:
- file_name: Screenshot_2024-06-13_at_20.29.45-B4517.png
  content: |-
    Here's the text extracted from the image:

    ```python
    @njit
    def signal_func_nb(ctx, entries, exits, wait):
        is_entry = vbt.pf_nb.select_nb(ctx, entries)
        if is_entry:
            return True, False, False, False
        is_exit = vbt.pf_nb.select_nb(ctx, exits)
        if is_exit:
            if vbt.pf_nb.in_position_nb(ctx):
                last_order = vbt.pf_nb.get_last_order_nb(ctx)
                if ctx.index[ctx.i] - ctx.index[last_order["idx"]] >= wait:
                    return False, True, False, False
        return False, False, False, False

    pf = vbt.PF.from_random_signals(
        "BTC-USD",
        n=100,
        seed=42,
        signal_func_nb=signal_func_nb,
        signal_args=(
            vbt.Rep("entries"),
            vbt.Rep("exits"),
            vbt.dt.to_ns(vbt.timedelta("1000 days"))
        )
    )
    ```
reactions: 0
````
