メインコンテンツへスキップ

概要

search_notes はノート探索の深い階層です。必須のキーワードを受け取り、一致したノートに主要ドキュメント(ワンページャー、カスタム)を付与して返します。LLM が、単に一致するノートを見るだけでなく、トピックの背後にあるコンテキスト(決定事項、アクションアイテム、結論)を理解する必要があるときに使用してください。 軽量なメタデータのみの一覧表示(例: 「フォルダ X にはどのノートがありますか」)には、代わりに list_notes を使用してください。 主なユースケース:
  • 「OKR Q2 についてチームは何を決めたのか?」 — トピックで検索し、ドキュメントをインラインで読む。
  • 「この決定のソースノートはどこか?」 — キーワードでノートを見つけ、ドキュメントがコンテキストを与える。
  • 「네이버 について書いたものをすべて見せて」 — 韓国語のキーワード検索をコンテンツ付きで。
主な特長:
  • キーワード必須。結果は全文検索の関連度(同点の場合は createdAt の降順)で並べ替えられます。
  • 一致した各ノートには、主要ドキュメント(ワンページャー、カスタム)がインラインで付きます。
  • ドキュメントのコンテンツから HTML を除去します。5,000 文字を超えるドキュメントは打ち切られ、フラグが付きます。
  • 検索インデックスが利用できない場合の優雅な縮退。
list_notes より重い。 各結果にはドキュメントのコンテンツが含まれます(ノートあたり ~1,500 トークン)。デフォルトのページサイズは 50、最大 200 です。メタデータのみが必要な場合は list_notes を使用してください。

パラメータ

ParameterTypeRequiredDescription
keywordstringYes検索キーワード(1 文字以上)。タイトルと段落のコンテンツに対して全文一致します。
pagination.cursorstringOptional将来の使用のために予約。深い検索 endpoint は現在 null を返します。
pagination.sizenumberOptional1 ページあたりの結果数(デフォルト 50、最大 200)。
filter.folderIdstringOptionalフォルダに限定(再帰的 — 子孫フォルダを含みます)。
filter.createdAtFromstringOptionalISO 8601 形式の日時。createdAt の下限(その値を含む)。
filter.createdAtTostringOptionalISO 8601 形式の日時。createdAt の上限(その値を含まない)。

keyword (required)

検索語です。サーバー側でトークン化され、韓国語テキストは形態素解析されます(例: 네이버[네, 버])。空または空白のみのキーワードは 400 を返します。 キーワード検索には現在、ユーザースコープの API key が必要です。チーム専用 API key は 400 を返します。

filter.folderId (optional)

list_notes と同じ意味です。再帰的なフォルダ範囲で、サーバー側で認可されます。

pagination (optional)

{ cursor, size }。デフォルト size: 50、最大 200。この上限は、結果あたりのコストが高いこと(各ノートがドキュメントを伴うこと)を反映しています。

レスポンス形式

成功レスポンス

{
  "notes": [
    {
      "noteGuid": "abc-123-def",
      "title": "OKR Q2 Planning",
      "webUrl": "https://platform.tiro.ooo/notes/abc-123-def",
      "createdAt": "2026-04-15T10:00:00Z",
      "updatedAt": "2026-04-15T11:30:00Z",
      "recordingDurationSeconds": 3625,
      "sourceType": "live-voice",
      "participants": [
        { "name": "Alice Kim", "email": "alice@example.com" }
      ],
      "matchedSnippets": null,
      "documents": [
        {
          "documentGuid": "7821",
          "templateId": 12,
          "templateTitle": "One Pager",
          "content": "## 결정 사항\n- 자동 ingest 우선...\n## Action Items\n- ...",
          "truncated": false,
          "updatedAt": "2026-04-15T11:30:00Z"
        }
      ]
    }
  ],
  "nextCursor": null,
  "degraded": false,
  "degradedReason": null
}
フィールドの説明:
FieldTypeDescription
notes[]array一致したノート。全文検索の関連度(同点の場合は createdAt の降順)で並べ替えられます。
notes[].matchedSnippetsstring[] | nullハイライトスニペット用に予約。現在は null で、「ハイライトが未実装」と「検索したがハイライトが一致しなかった」を区別します。
notes[].documents[]arrayノートの主要ドキュメント。ノートにドキュメントがない場合は空配列。
notes[].documents[].documentGuidstring安定したドキュメント識別子。
notes[].documents[].templateIdnumber | null数値のテンプレート ID。唯一の安定した判別子です。
notes[].documents[].templateTitlestring表示用ラベル(例: "One Pager""회의록")。ロケール依存で、カスタムテンプレートではユーザーが編集可能です。この文字列で判別しないでください。
notes[].documents[].contentstringHTML 除去済み、Markdown 対応のテキスト。5,000 文字で打ち切り。truncated を参照。
notes[].documents[].truncatedbooleanコンテンツが打ち切られた場合は true。残りが必要な場合は get_note(include: ['documents']) でドキュメント全文を取得してください。
nextCursorstring | null将来の使用のために予約。現在は常に null
degradedboolean検索インデックスが利用できなかった、または失敗した場合は true
degradedReasonstring | nulldegraded=true の場合: "search_index_unavailable" または "search_index_degraded"
templateTitle で判別しないでください。 これは表示用ラベルであり、enum ではありません。ブール値のチェック(「これはワンページャーか?」)には、既知の管理済みテンプレート ID に対して templateId を使用するか、両方のフィールドを提示して UI にラベルで選ばせてください。

縮退レスポンス

検索インデックスが利用できない場合、レスポンスは degraded=true を設定し、空の notes 配列を返します。
{
  "notes": [],
  "nextCursor": null,
  "degraded": true,
  "degradedReason": "search_index_unavailable"
}
degradedReason は次のいずれかです。
  • search_index_unavailable — この環境では検索インデックスが無効になっています。
  • search_index_degraded — クエリの途中で検索インデックスがエラーを投げました。
リトライを延期したり結果を適切に解釈したりできるよう、これを LLM/ユーザーに提示してください。

使用例

例 1: トピック検索

リクエスト:
{
  "keyword": "OKR"
}
OKR に言及する最も関連度の高いノート 10 件を、それぞれの主要ドキュメントをインラインで付けて返します。

例 2: フォルダ限定の韓国語キーワード

リクエスト:
{
  "keyword": "네이버",
  "filter": {
    "folderId": "455765"
  },
  "pagination": {
    "size": 5
  }
}
フォルダ 455765(とその子孫)の中だけで 네이버 を検索します。韓国語の形態素解析はサーバー側で実行されます。

例 3: 日付で区切った深い検索

リクエスト:
{
  "keyword": "release",
  "filter": {
    "createdAtFrom": "2026-04-01T00:00:00Z",
    "createdAtTo": "2026-05-01T00:00:00Z"
  }
}

ベストプラクティス

まず list_notes を使って、どのノートが一致するかを見つけてください。LLM が答えるためにドキュメントの内容をなお必要とする場合は、同じキーワードで search_notes に切り替えます。これが最も安価な段階的開示のパスです。
フォルダ限定の検索は、関連度の空間が小さくなるため、より高速で、より良くランク付けされた結果を返します。まず list_notes(filter.folderId) と組み合わせてフォルダ候補を見つけてください。
深い検索 endpoint は現在 nextCursor: null を返します。30 件の結果で足りない場合は、ページネーションするのではなく、キーワードを絞り込む(より具体的に)か、folderId/dateRange で範囲を限定してください。
degraded=true のレスポンスは正直です。検索インデックスが実行できなかったのです。空の notes 配列を「一致なし」と扱わないでください。代わりに、リトライのタイミングを適切に計れるよう、縮退をユーザー/LLM に提示してください。

よくあるエラー

空のキーワード

チーム専用 API key

解決方法: ユーザースコープの API key を使用してください。チームフォルダのキーワード検索は今後対応予定です。

トークン使用量

ノートあたり(ドキュメント付き): 平均 ~1,500 トークン。打ち切られたドキュメントは、元のサイズにかかわらず ~1,500 トークンで頭打ちになります。
get_note_transcript(会議 1 時間あたり ~3,000–5,000 トークン)と比べてsearch_notes は通常 10 倍コンパクトで、同じ重要な決定事項をカバーする、整理されたドキュメントを返します。話された言葉そのものが必要なときにのみトランスクリプトを使ってください。