개요
search_notes는 노트 디스커버리의 심층 단계예요. 필수 keyword를 받아 주요 문서(one-pager, custom)와 함께 채워진 매칭 노트를 반환해요. 어떤 노트가 매칭되는지만 보는 게 아니라, LLM이 주제 이면의 결정, action item, 결론 등 맥락을 이해해야 할 때 사용하세요.
가벼운 메타데이터만 필요한 목록 조회(예: “폴더 X에 어떤 노트가 있지”)는 대신 list_notes를 사용하세요.
주요 사용 사례:
- “OKR Q2에 대해 팀이 무엇을 결정했지?” — 주제로 검색하고 문서를 inline으로 읽어요.
- “이 결정의 출처 노트가 어디 있지?” — keyword로 노트를 찾고 문서가 맥락을 줘요.
- “네이버에 대해 우리가 쓴 걸 다 보여줘” — 내용까지 포함한 한국어 keyword 검색.
- keyword 필수. 결과는 전문 검색 관련도(동점 시
createdAt내림차순)로 정렬돼요. - 매칭된 각 노트는 주요 문서(one-pager, custom)를 inline으로 담아요.
- 문서 내용에서 HTML이 제거돼요. 5,000자보다 큰 문서는 잘리고 표시돼요.
- 검색 인덱스를 사용할 수 없을 때 우아하게 성능 저하(graceful degradation)해요.
파라미터
| Parameter | Type | Required | Description |
|---|---|---|---|
keyword | string | Yes | 검색 keyword(1자 이상). 제목과 단락 내용을 기준으로 전문 검색 매칭. |
pagination.cursor | string | Optional | 향후 사용 예약. 심층 검색 endpoint는 현재 null을 방출해요. |
pagination.size | number | Optional | 페이지당 결과 수(기본값 50, 최대 200). |
filter.folderId | string | Optional | 폴더로 제한(재귀적 — 하위 폴더 포함). |
filter.createdAtFrom | string | Optional | ISO 8601 datetime, createdAt의 포함 하한. |
filter.createdAtTo | string | Optional | ISO 8601 datetime, createdAt의 배제 상한. |
keyword (필수)
검색어예요. 서버 측에서 토큰화돼요. 한국어 텍스트는 형태소 분석돼요(예:네이버 → [네, 버]). 비었거나 공백만 있는 keyword는 400을 반환해요.
keyword 검색은 현재 사용자 범위 API key가 필요해요. 팀 전용 API key는 400을 반환해요.
filter.folderId (선택)
list_notes와 의미가 같아요. 재귀적 폴더 범위이며 서버 측에서 인가돼요.
pagination (선택)
{ cursor, size }. 기본값 size: 50, 최대 200. 이 상한은 결과당 더 높은 비용(각 노트가 문서를 담음)을 반영해요.
응답 형식
성공 응답
| Field | Type | Description |
|---|---|---|
notes[] | array | 매칭된 노트, 전문 검색 관련도(동점 시 createdAt 내림차순)로 정렬. |
notes[].matchedSnippets | string[] | null | 하이라이트 스니펫용 예약. 현재 null로, “하이라이트 미구현”과 “검색했으나 매칭 하이라이트 없음”을 구분해요. |
notes[].documents[] | array | 노트의 주요 문서. 노트에 문서가 없으면 빈 배열. |
notes[].documents[].documentGuid | string | 안정적인 문서 식별자. |
notes[].documents[].templateId | number | null | 숫자 template id — 유일하게 안정적인 구분자. |
notes[].documents[].templateTitle | string | 표시 라벨(예: "One Pager", "회의록"). locale에 따라 달라지고 custom 템플릿은 사용자가 편집 가능 — 이 문자열로 구분하지 마세요. |
notes[].documents[].content | string | HTML 제거된 markdown 친화 텍스트. 5,000자로 제한. truncated를 참고하세요. |
notes[].documents[].truncated | boolean | 내용이 잘렸으면 true. 나머지가 필요하면 get_note(include: ['documents'])로 전체 문서를 가져오세요. |
nextCursor | string | null | 향후 사용 예약. 현재 항상 null. |
degraded | boolean | 검색 인덱스를 사용할 수 없거나 실패했으면 true. |
degradedReason | string | null | degraded=true일 때: "search_index_unavailable" 또는 "search_index_degraded". |
성능 저하 응답
검색 인덱스를 사용할 수 없으면 응답은degraded=true로 설정되고 빈 notes 배열을 반환해요:
degradedReason은 다음 중 하나예요:
search_index_unavailable— 이 환경에서 검색 인덱스가 비활성화됨.search_index_degraded— 쿼리 도중 검색 인덱스가 오류를 던짐.
사용 예시
예시 1: 주제 검색
요청:예시 2: 폴더 범위 한국어 keyword
요청:455765(및 하위)에서만 네이버를 검색해요. 한국어 형태소 분석이 서버 측에서 실행돼요.
예시 3: 날짜 범위 심층 검색
요청:권장 사례
list_notes로 시작하고, 내용이 필요하면 search_notes로 전환하기
list_notes로 시작하고, 내용이 필요하면 search_notes로 전환하기
먼저
list_notes로 어떤 노트가 매칭되는지 찾으세요. LLM이 답하기 위해 여전히 문서 내용이 필요하면 같은 keyword로 search_notes로 전환하세요. 가장 저렴한 점진적 공개 경로예요.folderId로 검색 범위 좁히기
folderId로 검색 범위 좁히기
폴더 범위 검색은 관련도 공간이 더 작아서 더 빠르고 순위가 더 좋은 결과를 반환해요. 폴더 후보를 먼저 찾으려면
list_notes(filter.folderId)와 함께 쓰세요.`nextCursor`로 반복하지 마세요
`nextCursor`로 반복하지 마세요
심층 검색 endpoint는 현재
nextCursor: null을 방출해요. 결과 30개로 부족하면 페이지네이션 대신 keyword를 더 구체적으로 다듬거나 folderId/dateRange로 범위를 좁히세요.`degraded` 플래그를 주시하세요
`degraded` 플래그를 주시하세요
degraded=true 응답은 솔직한 신호예요. 검색 인덱스가 실행되지 못했어요. 빈 notes 배열을 “매칭 없음”으로 취급하지 말고, 재시도 타이밍을 적절히 잡을 수 있도록 성능 저하를 사용자/LLM에게 노출하세요.