Busabase

全域搜索

提供文件的可搜索文本,跨文件、Doc、记录和自定义提示词执行 grep,再按范围读取匹配内容。

Busabase 为用户和 AI 智能体提供一套完整的精确检索流程:

提供可搜索文本 -> grep -> 按范围读取匹配行

POST /api/v1/grep 会搜索文件、Doc 正文、Base 记录中当前已合并的值,以及保存在节点上的自定义智能体提示词。结果包含来源、行号、列号和上下文,调用方可以先定位证据,再读取更多内容。文件的匹配还会指明它属于哪个技能或网盘。

该用哪种搜索

智能体有三种找东西的方式,各自回答不同的问题:

你想知道用得到什么
这件事有没有现成的做法?playbooks search你保存的技能和自定义提示词,按匹配度排序、离得近的优先。智能体在每条指令开始时都会先调用它
这段文字具体出现在哪里?grep(本页)对完整的当前数据(文件、Doc 正文、已合并的记录、自定义提示词)做正则匹配,返回行号、列号和覆盖情况
相关的内容有哪些,最相关的排前面?search模糊匹配、排序、分页,也包含待审的变更请求草稿。较长的字段值只匹配前 8000 个字符,需要确认原文时请用 grep

哪些内容可以搜索

来源grep 使用的文本
文件Asset 的可搜索文本槽
Doc当前 Doc 正文
记录当前已合并的记录字段
提示词每条自定义智能体提示词的标题和正文,所有语言版本都会搜索

Markdown、JSON、CSV、日志和源代码等文本文件会直接使用自己的 UTF-8 字节作为可搜索文本。PDF、Office 文档、音频、视频或图片等二进制文件,需要外部工具或智能体先提取或转录文本,再将结果提供给 Asset。

Busabase 负责存储和搜索已提供的文本,但不会内置运行 OCR、语音转录或文档解析器。

为文件提供可搜索文本

Asset 的 textStatus 有四种状态:

状态含义下一步
missing尚未提供可搜索文本提供文本,或标记为没有可提取文本
present当前可搜索文本已经就绪执行 grep 或读取;有更好的提取结果时可替换
stale提供文本后,源文件又发生了变化提供从新文件生成的文本
none已明确标记为没有可提取文本将来有 OCR 或转录结果时仍可提供文本

Asset 详情页提供同样的添加、替换和预览操作。API 与智能体客户端支持三种写入方式。

小文本:直接写入

UTF-8 文本不超过 1 MB 时,直接调用 putText:

curl -X PUT "$BUSABASE_BASE_URL/api/v1/assets/$ASSET_ID/text" \
  -H "Authorization: Bearer $BUSABASE_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"text":"提取后的合同文本\n终止条款……"}'

响应会返回持久化后的状态与计数:

{
  "assetId": "asset_contract_pdf",
  "textStatus": "present",
  "lineCount": 84,
  "charCount": 4921,
  "byteCount": 8036
}

大文本:先上传,再绑定

文本超过 1 MB 时,使用适合流式处理的三步流程:

  1. 调用 POST /api/v1/assets/text/upload-urls 获取临时上传地址。
  2. 将 UTF-8 .txt 字节 PUT 到返回的 uploadUrl。
  3. 调用 PUT /api/v1/assets/{assetId}/text,绑定返回的 storageKey。
SIZE_BYTES=$(wc -c < extracted.txt | tr -d ' ')

curl -X POST "$BUSABASE_BASE_URL/api/v1/assets/text/upload-urls" \
  -H "Authorization: Bearer $BUSABASE_API_KEY" \
  -H "Content-Type: application/json" \
  --data "{\"assetId\":\"$ASSET_ID\",\"sizeBytes\":$SIZE_BYTES}"
# -> { "uploadUrl": "...", "storageKey": "...", "expiresIn": 900 }

curl -X PUT "<uploadUrl>" \
  -H "Content-Type: text/plain; charset=utf-8" \
  --data-binary @extracted.txt

curl -X PUT "$BUSABASE_BASE_URL/api/v1/assets/$ASSET_ID/text" \
  -H "Authorization: Bearer $BUSABASE_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"storageKey":"<storageKey>"}'

最后一步会校验上传的字节和 UTF-8 编码,并让文本进入可搜索状态。再次提供文本会替换之前的可搜索文本。

没有可提取文本:标记为 none

对于纯图片或其他无法提取文本的文件,明确标记文本槽:

curl -X PUT "$BUSABASE_BASE_URL/api/v1/assets/$ASSET_ID/text" \
  -H "Authorization: Bearer $BUSABASE_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"none":true}'

之后 grep 会将该 Asset 计入 unsearchable,而不会反复报告为 missing。将来可以通过提供文本撤销这一状态。

跨文件、Doc、记录和提示词执行 grep

省略 sources 即搜索全部四类来源,也可以只选择需要的来源:

curl -X POST "$BUSABASE_BASE_URL/api/v1/grep" \
  -H "Authorization: Bearer $BUSABASE_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "pattern":"termination",
    "flags":"i",
    "sources":["files","nodes","records","prompts"],
    "contextLines":2
  }'

pattern 使用 JavaScript 正则表达式语法,普通单词本身也是合法 pattern。对于大型搜索,可以用 scope.files、scope.nodes 或 scope.records 缩小范围。

{
  "matches": [
    {
      "source": "files",
      "assetId": "asset_contract_pdf",
      "fileName": "contract.pdf",
      "drivePath": "legal/contract.pdf",
      "owner": { "nodeId": "nod_legal", "nodeType": "drive", "nodeName": "Legal", "path": ["Company"] },
      "line": 118,
      "column": 1,
      "text": "Termination requires 30 days notice.",
      "before": ["..."],
      "after": ["..."]
    },
    {
      "source": "prompts",
      "nodeId": "nod_contracts",
      "nodeName": "Contracts",
      "nodeType": "base",
      "nodeSlug": "contracts",
      "key": "check-termination",
      "locale": "en",
      "field": "body",
      "line": 2,
      "column": 12,
      "text": "Flag any termination clause shorter than 30 days.",
      "before": ["..."],
      "after": []
    }
  ],
  "coverage": {
    "files": { "scanned": 24, "missing": [], "stale": [], "unsearchable": 1, "errored": [], "notReached": 0 },
    "nodes": { "scanned": 12, "errored": [], "notReached": 0 },
    "records": { "scanned": 178, "errored": [], "notReached": 0 },
    "prompts": { "scanned": 3, "errored": [], "notReached": 0 }
  },
  "truncated": false
}

每类匹配告诉你的信息:

  • 文件的匹配带有 owner:文件所属的节点(nodeType、nodeName)以及它上方的文件夹(path)。所以在 SKILL.md 里的命中会直接说明是哪个技能。你无权打开的文件夹不会出现在 path 里。已上传但还没放到任何位置的文件没有 owner。
  • 提示词的匹配会给出提示词所在的节点、提示词的 key、命中的 field(label 标题或 body 正文),以及这段文字的 locale(提示词只有一份、不分语言时为 default)。要按智能体实际收到的样子打开这条提示词,把 key 交给 playbooks get。要为某件事找合适的提示词,请用 playbooks search:grep 列出每一处匹配,playbooks search 负责排序。

maxMatches 会公平分配。每个被请求的来源至少能拿到 maxMatches ÷ 来源数 条匹配,某个来源没用完的额度会顺延给排在它后面的来源,顺序是文件、Doc、记录、提示词。一个匹配特别多的来源不会挤掉其他来源。整次调用也只共用一个时间上限。

在把零匹配解释为“确实不存在”之前,务必检查 coverage。出现 missing、stale、errored、notReached 或 truncated: true,说明搜索并不完整。缺失或过期的文件需要补充新文本。notReached 或截断意味着应该缩小搜索范围,而不是调大 maxMatches:先用 sources 选出需要的来源,再用 scope.records.baseSlugs 缩小记录范围,或用 scope.files.drivePath 缩小文件范围。

只读取匹配附近的范围

文件在第 118 行命中后,只读取附近窗口,不必下载完整提取文本:

curl "$BUSABASE_BASE_URL/api/v1/assets/$ASSET_ID/text/lines?startLine=113&endLine=123" \
  -H "Authorization: Bearer $BUSABASE_API_KEY"

如果命中来自 Doc,则使用结果中的 nodeId 调用对应的 Doc 接口:

curl "$BUSABASE_BASE_URL/api/v1/docs/$NODE_ID/lines?startLine=113&endLine=123" \
  -H "Authorization: Bearer $BUSABASE_API_KEY"

Asset 单次读取最多 2,000 行,并使用存储范围读取,因此“先 grep、再读取”的方式同样适用于非常大的提取文本。

putText 不等于 editContent

这两个操作修改的对象和审核规则完全不同:

操作修改内容源文件审核方式
assets.putTextgrep 和范围读取使用的、可重新生成的派生文本不变直接写入,并记录审计日志
assets.editContent挂载在 Drive 或 Skill 中的标准文本文件字节合并后改变创建 ChangeRequest——有写权限时直接合并,否则等待审核

不要使用 putText 编辑 PDF、文档或已挂载文本文件本身。它只负责提供 grep 读取的文本表示。只有需要修改真实文件时,才使用 editContent。

Asset 响应中不会内联提供 asset.text 字段。大文本不会进入 AssetVO;请通过 asset.textStatus 查看状态,用 putText 写入,用 grep 搜索,再用 readTextLines 按范围读取。

另请参阅:REST API · MCP 集成 · 核心概念

On this page