{"meta":{"title":"引用","intro":"引用は、アシスタントの応答内の該当箇所を、それを裏付けるソースにリンクします。 セッションを作成または再開するときにenableCitationsを有効にしてから、assistant.message イベントのcitations ペイロードを読み取り、脚注、ソース リスト、またはインライン リンクをレンダリングします。","product":"GitHub Copilot","breadcrumbs":[{"href":"/ja/copilot","title":"GitHub Copilot"},{"href":"/ja/copilot/how-tos","title":"方法"},{"href":"/ja/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/ja/copilot/how-tos/copilot-sdk/features","title":"機能"},{"href":"/ja/copilot/how-tos/copilot-sdk/features/citations","title":"引用"}],"documentType":"article"},"body":"# 引用\n\n引用は、アシスタントの応答内の該当箇所を、それを裏付けるソースにリンクします。 セッションを作成または再開するときにenableCitationsを有効にしてから、assistant.message イベントのcitations ペイロードを読み取り、脚注、ソース リスト、またはインライン リンクをレンダリングします。\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n> \\[!WARNING]\n> 引用文献は試験的です。 オプション名、イベント ペイロード、プロバイダー カバレッジは、将来のリリースで変更される可能性があります。\n\n## 引用文献のしくみ\n\n引用は、SDK ではなくモデル プロバイダーによって生成されます。 フローには、次の 3 つの部分があります。\n\n1. アプリケーションは、ドキュメントの添付ファイルやソース コンテンツを含むツールの結果など、引用可能な資料を提供します。\n2. ランタイムは、`enableCitations` がオンのとき、そのマテリアルをワイヤ上で引用可能としてマークします。 Anthropicモデルの場合、添付ファイルは引用文献が有効になっている`document`ブロックとして送信されます。\n3. モデルは引用メタデータを返し、ランタイムは最終的な`assistant.message` イベントでプロバイダーに依存しない`citations` オブジェクトに正規化します。\n\nプロバイダーのサポートは制限されています。 各ソースレコードの `provider` フィールドには、引用の出典元が記録されます:\n\n| プロバイダーの値    | 意味                                |\n| ----------- | --------------------------------- |\n| `anthropic` | Anthropic (クロード) モデル応答によって生成された引用 |\n| `openai`    | OpenAI モデル応答によって生成された引用           |\n| `client`    | ツール出力からランタイムによって合成された引用           |\n\n> \\[!NOTE]\n> `enableCitations`を有効にしても、応答に引用文献が含まれるとは限りません。 モデルは、応答が引用可能なソース マテリアルに接地されている場合にのみ、それらを出力します。 `citations` フィールドは常に省略可能として扱います。\n\n## セッションで引用を有効にする\n\nセッション作成のオプションを設定し、再起動後に引用を行う場合は、再開時にもう一度設定します。\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n<!-- docs-validate: skip -->\n\n```typescript\nconst session = await client.createSession({\n    onPermissionRequest: approveAll,\n    enableCitations: true,\n});\n\nconst resumed = await client.resumeSession(session.sessionId, {\n    onPermissionRequest: approveAll,\n    enableCitations: true,\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n<!-- docs-validate: skip -->\n\n```python\nsession = await client.create_session(\n    on_permission_request=PermissionHandler.approve_all,\n    enable_citations=True,\n)\n\nresumed = await client.resume_session(\n    session.session_id,\n    on_permission_request=PermissionHandler.approve_all,\n    enable_citations=True,\n)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n<!-- docs-validate: skip -->\n\n```golang\nsession, err := client.CreateSession(ctx, &copilot.SessionConfig{\n    OnPermissionRequest: copilot.PermissionHandler.ApproveAll,\n    EnableCitations:     copilot.Bool(true),\n})\n\nresumed, err := client.ResumeSession(ctx, session.SessionID, &copilot.ResumeSessionConfig{\n    OnPermissionRequest: copilot.PermissionHandler.ApproveAll,\n    EnableCitations:     copilot.Bool(true),\n})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n<!-- docs-validate: skip -->\n\n```csharp\nvar session = await client.CreateSessionAsync(new SessionConfig\n{\n    OnPermissionRequest = PermissionHandler.ApproveAll,\n    EnableCitations = true,\n});\n\nvar resumed = await client.ResumeSessionAsync(session.SessionId, new ResumeSessionConfig\n{\n    OnPermissionRequest = PermissionHandler.ApproveAll,\n    EnableCitations = true,\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nCopilotSession session = client\n        .createSession(new SessionConfig()\n                .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)\n                .setEnableCitations(true))\n        .get();\n\nCopilotSession resumed = client\n        .resumeSession(session.getSessionId(), new ResumeSessionConfig()\n                .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)\n                .setEnableCitations(true))\n        .get();\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n<!-- docs-validate: skip -->\n\n```rust\nlet session = client\n    .create_session(\n        SessionConfig::new()\n            .approve_all_permissions()\n            .with_enable_citations(true),\n    )\n    .await?;\n\nlet resumed = client\n    .resume_session(\n        ResumeSessionConfig::new(session.id().clone())\n            .approve_all_permissions()\n            .with_enable_citations(true),\n    )\n    .await?;\n```\n\n</div>\n\n</div>\n\n## アシスタント メッセージから引用文献を読む\n\n引用文献は、`assistant.message_delta`イベントではなく、最終的な`assistant.message`イベントに到着します。 ソース マーカーをレンダリングする前に、最後のメッセージを待ちます。\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n<!-- docs-validate: skip -->\n\n```typescript\nsession.on((event) => {\n    if (event.type !== \"assistant.message\" || !event.data.citations) {\n        return;\n    }\n\n    const { sources, spans } = event.data.citations;\n    const sourceById = new Map(sources.map((source) => [source.id, source]));\n\n    for (const span of spans) {\n        const quoted = event.data.content.slice(span.startIndex, span.endIndex);\n        for (const reference of span.references) {\n            const source = sourceById.get(reference.sourceId);\n            const label = source?.title ?? source?.url ?? source?.path ?? source?.id;\n            console.log(`\"${quoted}\" — ${label}`);\n        }\n    }\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n<!-- docs-validate: skip -->\n\n```python\nfrom copilot.session_events import SessionEventType\n\ndef utf16_slice(text: str, start: int, end: int) -> str:\n    \"\"\"Slice by UTF-16 code units, which is how span offsets are measured.\"\"\"\n    units = text.encode(\"utf-16-le\")\n    return units[start * 2 : end * 2].decode(\"utf-16-le\")\n\ndef handle(event):\n    if event.type != SessionEventType.ASSISTANT_MESSAGE or not event.data.citations:\n        return\n\n    sources = {source.id: source for source in event.data.citations.sources}\n\n    for span in event.data.citations.spans:\n        quoted = utf16_slice(event.data.content, span.start_index, span.end_index)\n        for reference in span.references:\n            source = sources[reference.source_id]\n            label = source.title or source.url or source.path or source.id\n            print(f'\"{quoted}\" — {label}')\n\nsession.on(handle)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n<!-- docs-validate: skip -->\n\n```golang\n// import \"unicode/utf16\"\n\nsession.On(func(event copilot.SessionEvent) {\n    d, ok := event.Data.(*copilot.AssistantMessageData)\n    if !ok || d.Citations == nil {\n        return\n    }\n\n    sources := map[string]copilot.CitationSource{}\n    for _, source := range d.Citations.Sources {\n        sources[source.ID] = source\n    }\n\n    // Span offsets are UTF-16 code units, so index the UTF-16 view of the content.\n    units := utf16.Encode([]rune(d.Content))\n\n    for _, span := range d.Citations.Spans {\n        quoted := string(utf16.Decode(units[span.StartIndex:span.EndIndex]))\n        for _, reference := range span.References {\n            source := sources[reference.SourceID]\n            label := source.ID\n            switch {\n            case source.Title != nil:\n                label = *source.Title\n            case source.URL != nil:\n                label = *source.URL\n            case source.Path != nil:\n                label = *source.Path\n            }\n            fmt.Printf(\"%q — %s\\n\", quoted, label)\n        }\n    }\n})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n<!-- docs-validate: skip -->\n\n```csharp\nsession.On<SessionEvent>(evt =>\n{\n    if (evt is not AssistantMessageEvent message || message.Data.Citations is null)\n    {\n        return;\n    }\n\n    var sources = message.Data.Citations.Sources.ToDictionary(source => source.Id);\n\n    foreach (var span in message.Data.Citations.Spans)\n    {\n        var quoted = message.Data.Content[(int)span.StartIndex..(int)span.EndIndex];\n        foreach (var reference in span.References)\n        {\n            var source = sources[reference.SourceId];\n            var label = source.Title ?? source.Url ?? source.Path ?? source.Id;\n            Console.WriteLine($\"\\\"{quoted}\\\" — {label}\");\n        }\n    }\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nsession.on(AssistantMessageEvent.class, event -> {\n    Citations citations = event.getData().citations();\n    if (citations == null) {\n        return;\n    }\n\n    Map<String, CitationSource> sources = citations.sources().stream()\n            .collect(Collectors.toMap(CitationSource::id, source -> source));\n\n    for (CitationSpan span : citations.spans()) {\n        String quoted = event.getData().content()\n                .substring(span.startIndex().intValue(), span.endIndex().intValue());\n        for (CitationReference reference : span.references()) {\n            CitationSource source = sources.get(reference.sourceId());\n            String label = source.title() != null ? source.title()\n                    : source.url() != null ? source.url()\n                    : source.path() != null ? source.path()\n                    : source.id();\n            System.out.printf(\"\\\"%s\\\" — %s%n\", quoted, label);\n        }\n    }\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n<!-- docs-validate: skip -->\n\n```rust\nuse github_copilot_sdk::session_events::AssistantMessageData;\nuse std::collections::HashMap;\n\nlet mut events = session.subscribe();\n\nwhile let Ok(event) = events.recv().await {\n    if event.event_type != \"assistant.message\" {\n        continue;\n    }\n\n    let Some(data) = event.typed_data::<AssistantMessageData>() else {\n        continue;\n    };\n    let Some(citations) = data.citations.as_ref() else {\n        continue;\n    };\n\n    let sources: HashMap<&str, _> = citations\n        .sources\n        .iter()\n        .map(|source| (source.id.as_str(), source))\n        .collect();\n\n    // Span offsets are UTF-16 code units, so index the UTF-16 view of the content.\n    let units: Vec<u16> = data.content.encode_utf16().collect();\n\n    for span in &citations.spans {\n        let quoted = String::from_utf16_lossy(\n            &units[span.start_index as usize..span.end_index as usize],\n        );\n        for reference in &span.references {\n            let Some(source) = sources.get(reference.source_id.as_str()) else {\n                continue;\n            };\n            let label = source\n                .title\n                .as_deref()\n                .or(source.url.as_deref())\n                .or(source.path.as_deref())\n                .unwrap_or(source.id.as_str());\n            println!(\"\\\"{quoted}\\\" — {label}\");\n        }\n    }\n}\n```\n\n</div>\n\n</div>\n\n## 引用ペイロードの参照\n\n`citations` オブジェクトは重複除去されたソースを参照するスパンから分離するため、5 回引用されたソースが`sources`に 1 回表示されます。\n\n| タイプ                                                  | フィールド               | Description                                           |\n| ---------------------------------------------------- | ------------------- | ----------------------------------------------------- |\n| `Citations`                                          | `sources`           | 引用スパンで参照される、重複が除去されたソースのセット                           |\n| `Citations`                                          | `spans`             | 根拠ソースで注釈された生成テキストの範囲                                  |\n| `CitationSource`                                     | `id`                |                                                       |\n| `CitationReference.sourceId` によって参照される安定したターンスコープ識別子 |                     |                                                       |\n| `CitationSource`                                     | `provider`          | 引用文献を作成したシステム: `anthropic`、 `openai`、または `client`     |\n| `CitationSource`                                     | `title?`            | ソースの人間が判読できるタイトル                                      |\n| `CitationSource`                                     | `url?`              | ソースの URL (Web リソースの場合)                                |\n| `CitationSource`                                     | `path?`             | ソースがファイルの場合、エージェント ワークスペース のルートを基準としたファイル パス          |\n| `CitationSpan`                                       | `startIndex`        | 最終メッセージ コンテンツ内の開始オフセット (UTF-16 コード単位、ゼロベース、含む)        |\n| `CitationSpan`                                       | `endIndex`          | 最終メッセージのコンテンツ内の終了オフセット (UTF-16 コード単位、0 始まり、終了位置を含まない) |\n| `CitationSpan`                                       | `references`        | このスパンをサポートするソース                                       |\n| `CitationReference`                                  | `sourceId`          | この参照が指す `CitationSource` の識別子                         |\n| `CitationReference`                                  | `citedText?`        | スパンをサポートするソースからの正確なテキスト (モデルが提供する場合)                  |\n| `CitationReference`                                  | `location?`         | 該当範囲の根拠となるソース内の位置                                     |\n| `CitationReference`                                  | `providerMetadata?` | プロバイダーネイティブの関連付けデータ(不透明に渡される)                         |\n\n> \\[!TIP]\n> スパン オフセットは、最終的な `content` 文字列に対して UTF-16 コード単位で測定されます。 TypeScript、Java、および.NET文字列は既に UTF-16 であるため、直接スライスできます。 Python文字列は Unicode コード ポイントによってインデックスが作成され、Go 文字列と Rust 文字列は UTF-8 であるため、上記の例のように、スライスする前にコンテンツを UTF-16 コード 単位に変換します。\n\n### 引用場所\n\n`CitationReference.location` は、 `type`でキー指定された判別共用体です。\n\n| 場所のタイプ                  | フィールド                   | 使用 |\n| ----------------------- | ----------------------- | -- |\n| `char`                  |                         |    |\n| `startIndex`、`endIndex` | ソース テキスト内の文字範囲          |    |\n| `page`                  |                         |    |\n| `startPage`、`endPage`   | ページ分割されたドキュメント内のページ範囲   |    |\n| `block`                 |                         |    |\n| `startBlock`、`endBlock` | 構造化ドキュメント内のコンテンツ ブロック範囲 |    |\n\n## 引用可能なソースを提供する\n\n引用文献には、モデルが属性付けできるソース マテリアルが必要です。 これを提供するには、2 つの方法があります。\n\n### メッセージにドキュメントを添付する\n\n引用が有効になっていて、セッションでAnthropicプロバイダーが使用されている場合、添付ファイルは引用がオンになっている`document` ブロックとして送信されるため、モデルはそれらの一節を引用できます。\n\n<!-- docs-validate: skip -->\n\n```typescript\nawait session.sendAndWait({\n    prompt: \"Summarize the attached PDF and cite the passages you used.\",\n    attachments: [\n        {\n            type: \"blob\",\n            data: pdfBase64,\n            displayName: \"quarterly-report.pdf\",\n            mimeType: \"application/pdf\",\n        },\n    ],\n});\n```\n\n`file` では、attachment API と `blob`および[](/ja/copilot/how-tos/copilot-sdk/features/image-input) attachment shapes について説明しています。\n\n### ツールから引用可能なソースを返す\n\nツールの結果には、実験的な `citableSources` 配列が含まれます。 各エントリは、モデルが引用できる `content` と、 `id` とオプションの `title`、 `url`、および `path`を提供します。 これらのソースはツールの結果と共に保持されるため、セッションの再開後も存続し、そこから構築された引用文献には `client` プロバイダーでタグ付けされます。\n\n## Limitations\n\n* 引用文献はすべての SDK で試験的であり、互換性の保証の対象ではありません。\n* カバレッジはモデル プロバイダーによって異なります。 引用サポートなしでプロバイダー用に構成されたセッションは、 `citations` ペイロードを出力しません。\n* 引用は最終的な `assistant.message` イベントにのみ存在するため、ストリーミング コンシューマーは中間応答をレンダリングできません。\n* パブリックコードとIP重複に関する引用は、この領域の一部ではありません。\n\n## 詳細については、次を参照してください。\n\n* [ストリーミング セッション イベント](/ja/copilot/how-tos/copilot-sdk/features/streaming-events): セッション イベントを購読し、イベントの種類を絞り込む\n* [画像入力](/ja/copilot/how-tos/copilot-sdk/features/image-input): ファイルとメモリ内 BLOB をメッセージにアタッチする\n* [セッションの再開と永続化](/ja/copilot/how-tos/copilot-sdk/features/session-persistence): セッションを再開し、セッション オプションを再適用する\n* [SDK と CLI の互換性](/ja/copilot/how-tos/copilot-sdk/troubleshooting/compatibility): SDK と CLI の機能マトリックス"}