RAG 인용(RAG Citations)

RAG 인용(RAG Citations)

RAG용 Cohere Chat 엔드포인트가 생성하는 인용에 접근하고 활용하는 방법에 대한 가이드예요. 비스트리밍 및 스트리밍 모드 모두를 다룹니다 (API v2).

출처: 문서

본문

인용 접근(Accessing citations)

Chat 엔드포인트는 RAG 응답에 대해 세밀한(granular) 인용을 생성해요. 이 능력은 Command 모델 패밀리에 기본 제공됩니다.

다음 섹션들은 비스트리밍과 스트리밍 모드 모두에서 인용에 접근하는 방법을 설명해요.

비스트리밍(Non-streaming)

먼저, 모델 응답의 컨텍스트로 전달할 문서를 정의합니다.

Cohere 플랫폼

PYTHON

# ! pip install -U cohere
import cohere
import json

co = cohere.ClientV2(
    "COHERE_API_KEY"
)  # Get your free API key here: https://dashboard.cohere.com/api-keys

프라이빗 배포(Private deployment)

PYTHON

# ! pip install -U cohere
import cohere

co = cohere.ClientV2(
    api_key="",  # Leave this blank
    base_url="<YOUR_DEPLOYMENT_URL>",
)

PYTHON

documents = [
    {
        "data": {
            "title": "Tall penguins",
            "snippet": "Emperor penguins are the tallest.",
        }
    },
    {
        "data": {
            "title": "Penguin habitats",
            "snippet": "Emperor penguins only live in Antarctica.",
        }
    },
]

비스트리밍 모드(chat로 모델 응답 생성)에서는 인용이 응답 객체의 message.citations 필드에 제공됩니다.

각 인용 객체에는 다음이 포함됩니다:

  • start 및 end: 소스를 인용하는 텍스트의 시작 및 끝 인덱스
  • text: 그에 해당하는 텍스트 범위(span)
  • sources: 참조하는 소스

PYTHON

messages = [
    {"role": "user", "content": "Where do the tallest penguins live?"}
]

response = co.chat(
    model="command-r-08-2024",
    messages=messages,
    documents=documents,
)

print(response.message.content[0].text)

for citation in response.message.citations:
    print(citation, "\n")

cURL

curl --request POST \
  --url https://api.cohere.ai/v2/chat \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --header "Authorization: bearer ***" \
  --data '{
  "model": "command-r-08-2024",
  "messages": [
    {
      "role": "user",
      "content": "Where do the tallest penguins live?"
    }
  ],
  "documents": [
    {
      "data": {
        "title": "Tall penguins",
        "snippet": "Emperor penguins are the tallest."
      }
    },
    {
      "data": {
        "title": "Penguin habitats",
        "snippet": "Emperor penguins only live in Antarctica."
      }
    }
  ]
}'

예제 응답:

The tallest penguins are the Emperor penguins. They only live in Antarctica.

start=29 end=46 text='Emperor penguins.' sources=[DocumentSource(type='document', id='doc:0', document={'id': 'doc:0', 'snippet': 'Emperor penguins are the tallest.', 'title': 'Tall penguins'})] type='TEXT_CONTENT' 

start=65 end=76 text='Antarctica.' sources=[DocumentSource(type='document', id='doc:1', document={'id': 'doc:1', 'snippet': 'Emperor penguins only live in Antarctica.', 'title': 'Penguin habitats'})] type='TEXT_CONTENT' 

스트리밍(Streaming)

스트리밍 시나리오(chat_stream으로 모델 응답 생성)에서는 인용이 citation-start 이벤트에 제공됩니다.

각 인용 객체는 비스트리밍 시나리오와 동일한 필드를 포함합니다.

PYTHON

messages = [
    {"role": "user", "content": "Where do the tallest penguins live?"}
]

response = co.chat_stream(
    model="command-a-plus-05-2026",
    messages=messages,
    documents=documents,
)

response_text = ""
citations = []
for chunk in response:
    if chunk:
        if chunk.type == "content-delta":
            response_text += chunk.delta.message.content.text
            print(chunk.delta.message.content.text, end="")
        if chunk.type == "citation-start":
            citations.append(chunk.delta.message.citations)

for citation in citations:
    print(citation, "\n")

cURL

curl --request POST \
  --url https://api.cohere.ai/v2/chat \
  --header 'accept: text/event-stream' \
  --header 'content-type: application/json' \
  --header "Authorization: bearer ***" \
  --data '{
  "model": "command-a-plus-05-2026",
  "messages": [
    {
      "role": "user",
      "content": "Where do the tallest penguins live?"
    }
  ],
  "documents": [
    {
      "data": {
        "title": "Tall penguins",
        "snippet": "Emperor penguins are the tallest."
      }
    },
    {
      "data": {
        "title": "Penguin habitats",
        "snippet": "Emperor penguins only live in Antarctica."
      }
    }
  ],
  "stream": true
}'

예제 응답:

The tallest penguins are the Emperor penguins, which only live in Antarctica.

start=29 end=45 text='Emperor penguins' sources=[DocumentSource(type='document', id='doc:0', document={'id': 'doc:0', 'snippet': 'Emperor penguins are the tallest.', 'title': 'Tall penguins'})] type='TEXT_CONTENT' 

start=66 end=77 text='Antarctica.' sources=[DocumentSource(type='document', id='doc:1', document={'id': 'doc:1', 'snippet': 'Emperor penguins only live in Antarctica.', 'title': 'Penguin habitats'})] type='TEXT_CONTENT' 

문서 ID(Document ID)

문서를 컨텍스트로 전달할 때, document 객체의 id 필드에 사용자 지정 ID를 선택적으로 추가할 수 있어요. 이 ID는 엔드포인트가 인용 참조로 사용합니다.

id 필드를 제공하지 않으면 ID는 doc:<auto_generated_id> 형식으로 자동 생성됩니다. 예: doc:0.

다음은 사용자 지정 ID를 사용하는 예시예요. 여기서는 컨텍스트로 전달하는 두 문서 각각에 사용자 지정 ID 100과 101을 추가하고 있습니다.

PYTHON

# ! pip install -U cohere
import cohere
import json

co = cohere.ClientV2(
    "COHERE_API_KEY"
)  # Get your free API key here: https://dashboard.cohere.com/api-keys

documents = [
    {
        "data": {
            "title": "Tall penguins",
            "snippet": "Emperor penguins are the tallest.",
        },
        "id": "100",
    },
    {
        "data": {
            "title": "Penguin habitats",
            "snippet": "Emperor penguins only live in Antarctica.",
        },
        "id": "101",
    },
]

문서 ID가 제공되면 인용은 이 ID들을 사용해 문서를 참조합니다.

PYTHON

messages = [
    {"role": "user", "content": "Where do the tallest penguins live?"}
]

response = co.chat(
    model="command-a-plus-05-2026",
    messages=messages,
    documents=documents,
)

print(response.message.content[0].text)

cURL

curl --request POST \
  --url https://api.cohere.ai/v2/chat \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --header "Authorization: bearer ***" \
  --data '{
  "model": "command-a-plus-05-2026",
  "messages": [
    {
      "role": "user",
      "content": "Where do the tallest penguins live?"
    }
  ],
  "documents": [
    {
      "data": {
        "title": "Tall penguins",
        "snippet": "Emperor penguins are the tallest."
      },
      "id": "100"
    },
    {
      "data": {
        "title": "Penguin habitats",
        "snippet": "Emperor penguins only live in Antarctica."
      },
      "id": "101"
    }
  ]
}'

인용의 id 필드가 document 객체의 ID를 참조하는 것에 주목하세요.

예제 응답:

The tallest penguins are the Emperor penguins, which only live in Antarctica.

start=29 end=45 text='Emperor penguins' sources=[DocumentSource(type='document', id='100', document={'id': '100', 'snippet': 'Emperor penguins are the tallest.', 'title': 'Tall penguins'})] type='TEXT_CONTENT' 

start=66 end=77 text='Antarctica.' sources=[DocumentSource(type='document', id='101', document={'id': '101', 'snippet': 'Emperor penguins only live in Antarctica.', 'title': 'Penguin habitats'})] type='TEXT_CONTENT' 

대조적으로, ID가 제공되지 않은 경우의 인용 예시는 다음과 같아요.

예제 응답:

The tallest penguins are the Emperor penguins, which only live in Antarctica.

start=29 end=45 text='Emperor penguins' sources=[DocumentSource(type='document', id='doc:0', document={'id': 'doc:0', 'snippet': 'Emperor penguins are the tallest.', 'title': 'Tall penguins'})] type='TEXT_CONTENT' 

start=66 end=77 text='Antarctica.' sources=[DocumentSource(type='document', id='doc:1', document={'id': 'doc:1', 'snippet': 'Emperor penguins only live in Antarctica.', 'title': 'Penguin habitats'})] type='TEXT_CONTENT' 

인용 모드(Citation modes)

스트리밍 모드에서 RAG를 실행할 때 인용이 생성되고 제시되는 방식을 구성할 수 있어요. 지연 시간과 정밀도 요구에 따라 빠른 인용(fast citations) 또는 정확한 인용(accurate citations) 중에서 선택할 수 있습니다.

정확한 인용(Accurate citations)

모델이 먼저 답변을 생성하고, 전체 응답이 생성된 후 응답 텍스트의 특정 구간에 매핑되는 인용을 제공해요. 이 접근 방식은 약간 더 높은 지연 시간이 발생할 수 있지만, 인용 인덱스가 모델 답변의 최종 텍스트 구간과 더 정밀하게 정렬되도록 보장합니다.

이것이 기본 옵션이며, API 호출에 citation_options={"mode": "accurate"} 인자를 추가하면 명시적으로 지정할 수도 있어요.

다음은 위와 동일한 사전 정의된 messages 목록을 사용하는 예시입니다.

citation_options 모드를 accurate로 설정하면, 전체 응답이 생성된 후에 인용을 얻을 수 있어요.

PYTHON

documents = [
    {
        "data": {
            "title": "Tall penguins",
            "snippet": "Emperor penguins are the tallest.",
        },
        "id": "100",
    },
    {
        "data": {
            "title": "Penguin habitats",
            "snippet": "Emperor penguins only live in Antarctica.",
        },
        "id": "101",
    },
]

messages = [
    {"role": "user", "content": "Where do the tallest penguins live?"}
]

response = co.chat_stream(
    model="command-a-plus-05-2026",
    messages=messages,
    documents=documents,
    citation_options={"mode": "fast"},
)

response_text = ""
citations = []
for chunk in response:
    if chunk:
        if chunk.type == "content-delta":
            response_text += chunk.delta.message.content.text
            print(chunk.delta.message.content.text, end="")
        if chunk.type == "citation-start":
            citations.append(chunk.delta.message.citations)

print("\n")
for citation in citations:
    print(citation, "\n")

cURL

curl --request POST \
  --url https://api.cohere.ai/v2/chat \
  --header 'accept: text/event-stream' \
  --header 'content-type: application/json' \
  --header "Authorization: bearer ***" \
  --data '{
  "model": "command-a-plus-05-2026",
  "messages": [
    {
      "role": "user",
      "content": "Where do the tallest penguins live?"
    }
  ],
  "documents": [
    {
      "data": {
        "title": "Tall penguins",
        "snippet": "Emperor penguins are the tallest."
      },
      "id": "100"
    },
    {
      "data": {
        "title": "Penguin habitats",
        "snippet": "Emperor penguins only live in Antarctica."
      },
      "id": "101"
    }
  ],
  "citation_options": {
    "mode": "fast"
  },
  "stream": true
}'

예제 응답:

The tallest penguins are the Emperor penguins. They live in Antarctica.

start=29 end=46 text='Emperor penguins.' sources=[DocumentSource(type='document', id='100', document={'id': '100', 'snippet': 'Emperor penguins are the tallest.', 'title': 'Tall penguins'})] type='TEXT_CONTENT' 

start=60 end=71 text='Antarctica.' sources=[DocumentSource(type='document', id='101', document={'id': '101', 'snippet': 'Emperor penguins only live in Antarctica.', 'title': 'Penguin habitats'})] type='TEXT_CONTENT' 

빠른 인용(Fast citations)

모델이 응답을 생성하면서 인라인으로 인용을 생성해요. 스트리밍 모드에서는 모델이 특정 외부 컨텍스트를 사용하는 바로 그 순간에 주입된 인용을 볼 수 있어요. 이 접근 방식은 인용 정확도에서 약간 덜 정밀해지는 대가로 즉각적인 추적 가능성(traceability)을 제공합니다.

API 호출에 citation_options={"mode": "fast"} 인자를 추가하면 지정할 수 있어요.

citation_options 모드를 fast로 설정하면, 모델이 응답을 생성하는 동안 인라인으로 인용을 얻을 수 있어요.

PYTHON

documents = [
    {
        "data": {
            "title": "Tall penguins",
            "snippet": "Emperor penguins are the tallest.",
        },
        "id": "100",
    },
    {
        "data": {
            "title": "Penguin habitats",
            "snippet": "Emperor penguins only live in Antarctica.",
        },
        "id": "101",
    },
]

messages = [
    {"role": "user", "content": "Where do the tallest penguins live?"}
]

response = co.chat_stream(
    model="command-a-plus-05-2026",
    messages=messages,
    documents=documents,
    citation_options={"mode": "fast"},
)

response_text = ""
for chunk in response:
    if chunk:
        if chunk.type == "content-delta":
            response_text += chunk.delta.message.content.text
            print(chunk.delta.message.content.text, end="")
        if chunk.type == "citation-start":
            print(
                f" [{chunk.delta.message.citations.sources[0].id}]",
                end="",
            )

cURL

curl --request POST \
  --url https://api.cohere.ai/v2/chat \
  --header 'accept: text/event-stream' \
  --header 'content-type: application/json' \
  --header "Authorization: bearer ***" \
  --data '{
  "model": "command-a-plus-05-2026",
  "messages": [
    {
      "role": "user",
      "content": "Where do the tallest penguins live?"
    }
  ],
  "documents": [
    {
      "data": {
        "title": "Tall penguins",
        "snippet": "Emperor penguins are the tallest."
      },
      "id": "100"
    },
    {
      "data": {
        "title": "Penguin habitats",
        "snippet": "Emperor penguins only live in Antarctica."
      },
      "id": "101"
    }
  ],
  "citation_options": {
    "mode": "fast"
  },
  "stream": true
}'

예제 응답:

The tallest penguins [100] are the Emperor penguins [100] which only live in Antarctica. [101]

더 알아보기 (Learn more)