← ニュース一覧

Sazanami の技術概要を公開しました

合同会社ニシカワテクノロジーズは、2026年5月20日に公開したコーポレートサイトスターター Sazanami(パッケージ名: next-markdown-agent-search-starter)について、技術概要と関連リンクをまとめました。本記事は、社内エージェントや外部ツールが agent-search-index.json 経由で参照する際に、Sazanami の設計意図と実装の要点を把握できることを目的としています。

Sazanami とは

Sazanami は、人間向けの静的コーポレートサイトエージェント向けの機械可読な知識面 を、同じ Markdown ソースから生成する Next.js 15 スターターです。ニシカワテクノロジーズのコーポレートサイトで運用している構成(Markdown + next-intl による日英、DDD 4 層、ビルド時インデックス、読み取り専用 Search API)をベースに、会社固有情報を Example Corporation 等のプレースホルダーへ置き換えた公開版です。

タグライン: A corporate site starter that publishes itself for humans and agents.

技術スタック

項目内容
フレームワークNext.js 15(App Router)
言語TypeScript
スタイルTailwind CSS 4
多言語next-intlja / enas-needed ロケールプレフィックス)
本文レンダリングreact-markdown + remark-gfm
ランタイムNode.js 24(engines: >=24.0.0
CIGitHub Actions(main 向け)

コンテンツのソース・オブ・トゥルースはリポジトリ内の content/{locale}/ です。固定ページ、ニュース、財務サマリを Markdown の frontmatter(title, description, date 等)付きで管理します。

ビルド時の知識インデックス

npm run buildprebuildnpm run generate:agent-search-index が実行され、public/agent-search-index.json が生成されます。スクリプトは content/ を走査し、各エントリに次を格納します。

フィールド説明
id安定 ID。形式 {sourceKind}:{locale}:{slug}(例: page:ja:company, news:en:2026-05-21-sazanami-technical-overview
sourceKindpage(固定ページ)、news(ニュース)、financial(財務サマリ)のいずれか
path公開 URL パス(先頭・末尾スラッシュ付き。デフォルトロケール ja はプレフィックスなし、en/en/ 付き)
titlefrontmatter の title
descriptionfrontmatter の description
text検索用プレーンテキスト(title + description + 本文を Markdown 除去・空白正規化したもの)

トップレベル JSON の形状:

  • version — スキーマ版(現行 1
  • generatedAt — ビルド時の ISO 8601 UTC タイムスタンプ
  • locales — ロケールコードをキーとするエントリ配列のオブジェクト

HTTP では {origin}/agent-search-index.json として静的配信され、認証不要です。デプロイのたびに npm run build で再生成されます。

エージェント向け discovery リソース

Sazanami は、サイトを機械が発見・解釈するためのリソースを標準で提供します。

パス役割
/llms.txtLLM・クローラ向けの入口。サイト構成、推奨読み取り順(インデックス → SPEC → Search API)を記載
/SPEC.mdagent-search-index.json と Search API のスキーマ仕様(HTTP で配信)
/agent-search-index.jsonビルド時生成の全文インデックス
sitemap.xml通常ページに加え、上記 discovery URL を掲載
各ページ <head>discovery 用リンク要素

推奨される参照順序: (1) /llms.txt で全体像を把握 → (2) /SPEC.md でスキーマを確認 → (3) /agent-search-index.json で広い文脈を一括取得 → (4) 必要に応じて Search API で絞り込み。

Search API(POST /api/agent/search

ランタイムでは、生成済みインデックスをメモリ上で読み、トークンベースの簡易スコアリング(完全一致フレーズの加点、タイトル・description・本文へのトークン一致)でランキングします。ベクトル検索・BM25・外部検索 SaaS は使用しません。

リクエスト(JSON):

{
  "q": "leadership",
  "locale": "ja",
  "limit": 10
}
フィールド説明
qstring検索クエリ(正規化: トリム、連続空白圧縮、小文字化)
locale"ja" | "en"省略時 ja
limitnumber1〜50、省略時 10

レスポンス:

{
  "hits": [
    {
      "sourceKind": "page",
      "path": "/leadership/",
      "title": "Leadership",
      "description": "...",
      "snippet": "…クエリに関連する抜粋…"
    }
  ]
}

フルインデックスは返さず、hits のみです。

認証(本番): 環境変数 AGENT_SEARCH_API_KEY を設定した場合、Authorization: Bearer <キー> または X-API-Key: <キー> が必須です。本番でキー未設定のときは常に 401 です。キー未設定かつ NODE_ENV !== 'production' のときのみ、ローカル検証向けにキー省略が可能です。

デモサイト: 静的 discovery(/llms.txt, /SPEC.md, /agent-search-index.json)は認証なしで参照可能。Search API は本番デモでは API キー必須(鍵なしは 401)。

アーキテクチャ(DDD)

パス(例)役割
Domainsrc/domain/agent-search/AgentSearchQuery, SearchHit, AgentSearchResult
Applicationsrc/application/agent-search/SearchKnowledgeForAgentUseCase
Infrastructuresrc/infrastructure/agent-search/インデックス読込、スコアリング、Markdown ストリップ、インデックス生成スクリプト連携
Presentationsrc/app/api/agent/search/API Route、ページ UI

ページコンテンツ本体も同様に src/domain/content/ 以下で Repository パターンを用いています。

ニシカワテクノロジーズとの関係

本コーポレートサイト(nskw.tech)は、Sazanami と同型の仕組みで agent-search-index.json を生成しています。社内の対話エージェント REN DESK や開発ツールは、公開ページ・ニュース・財務サマリを Pull 型で参照する想定です。Sazanami はその実装を OSS 化したテンプレートであり、フォーク先で content/ と環境変数を差し替えて利用します。

利用の入口

  • GitHub で Use this template、または npx degit nishikawa-technologies/next-markdown-agent-search-starter#main my-site
  • 必須環境変数の例: NEXT_PUBLIC_APP_URL(canonical・OG の絶対 URL)
  • Search API を本番で使う場合: AGENT_SEARCH_API_KEY

詳細な手順・環境変数一覧はリポジトリの README(英語)および README.ja.md(日本語)を参照してください。背景や設計思想については、上記 note 記事に西川蓮(COO・対話型 AI)名義で掲載しています。