diff --git a/docs/docs/integrations/chat/anthropic.ipynb b/docs/docs/integrations/chat/anthropic.ipynb index 3b0fb9ee8f7..e17b7d2cdde 100644 --- a/docs/docs/integrations/chat/anthropic.ipynb +++ b/docs/docs/integrations/chat/anthropic.ipynb @@ -315,6 +315,163 @@ "ai_msg.tool_calls" ] }, + { + "cell_type": "markdown", + "id": "301d372f-4dec-43e6-b58c-eee25633e1a6", + "metadata": {}, + "source": [ + "## Citations\n", + "\n", + "Anthropic supports a [citations](https://docs.anthropic.com/en/docs/build-with-claude/citations) feature that lets Claude attach context to its answers based on source documents supplied by the user. When [document content blocks](https://docs.anthropic.com/en/docs/build-with-claude/citations#document-types) with `\"citations\": {\"enabled\": True}` are included in a query, Claude may generate citations in its response.\n", + "\n", + "### Simple example\n", + "\n", + "In this example we pass a [plain text document](https://docs.anthropic.com/en/docs/build-with-claude/citations#plain-text-documents). In the background, Claude [automatically chunks](https://docs.anthropic.com/en/docs/build-with-claude/citations#plain-text-documents) the input text into sentences, which are used when generating citations." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e5370e6e-5a9a-4546-848b-5f5bf313c3e7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'text': 'Based on the document, ', 'type': 'text'},\n", + " {'text': 'the grass is green',\n", + " 'type': 'text',\n", + " 'citations': [{'type': 'char_location',\n", + " 'cited_text': 'The grass is green. ',\n", + " 'document_index': 0,\n", + " 'document_title': 'My Document',\n", + " 'start_char_index': 0,\n", + " 'end_char_index': 20}]},\n", + " {'text': ', and ', 'type': 'text'},\n", + " {'text': 'the sky is blue',\n", + " 'type': 'text',\n", + " 'citations': [{'type': 'char_location',\n", + " 'cited_text': 'The sky is blue.',\n", + " 'document_index': 0,\n", + " 'document_title': 'My Document',\n", + " 'start_char_index': 20,\n", + " 'end_char_index': 36}]},\n", + " {'text': '.', 'type': 'text'}]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from langchain_anthropic import ChatAnthropic\n", + "\n", + "llm = ChatAnthropic(model=\"claude-3-5-haiku-latest\")\n", + "\n", + "messages = [\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": [\n", + " {\n", + " \"type\": \"document\",\n", + " \"source\": {\n", + " \"type\": \"text\",\n", + " \"media_type\": \"text/plain\",\n", + " \"data\": \"The grass is green. The sky is blue.\",\n", + " },\n", + " \"title\": \"My Document\",\n", + " \"context\": \"This is a trustworthy document.\",\n", + " \"citations\": {\"enabled\": True},\n", + " },\n", + " {\"type\": \"text\", \"text\": \"What color is the grass and sky?\"},\n", + " ],\n", + " }\n", + "]\n", + "response = llm.invoke(messages)\n", + "response.content" + ] + }, + { + "cell_type": "markdown", + "id": "69956596-0e6c-492b-934d-c08ed3c9de9a", + "metadata": {}, + "source": [ + "### Using with text splitters\n", + "\n", + "Anthropic also lets you specify your own splits using [custom document](https://docs.anthropic.com/en/docs/build-with-claude/citations#custom-content-documents) types. LangChain [text splitters](/docs/concepts/text_splitters/) can be used to generate meaningful splits for this purpose. See the below example, where we split the LangChain README (a markdown document) and pass it to Claude as context:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "04cc2841-7987-47a5-906c-09ea7fa28323", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'text': \"You can find LangChain's tutorials at https://python.langchain.com/docs/tutorials/\\n\\nThe tutorials section is recommended for those looking to build something specific or who prefer a hands-on learning approach. It's considered the best place to get started with LangChain.\",\n", + " 'type': 'text',\n", + " 'citations': [{'type': 'content_block_location',\n", + " 'cited_text': \"[Tutorials](https://python.langchain.com/docs/tutorials/):If you're looking to build something specific orare more of a hands-on learner, check out ourtutorials. This is the best place to get started.\",\n", + " 'document_index': 0,\n", + " 'document_title': None,\n", + " 'start_block_index': 243,\n", + " 'end_block_index': 248}]}]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import requests\n", + "from langchain_anthropic import ChatAnthropic\n", + "from langchain_text_splitters import MarkdownTextSplitter\n", + "\n", + "\n", + "def format_to_anthropic_documents(documents: list[str]):\n", + " return {\n", + " \"type\": \"document\",\n", + " \"source\": {\n", + " \"type\": \"content\",\n", + " \"content\": [{\"type\": \"text\", \"text\": document} for document in documents],\n", + " },\n", + " \"citations\": {\"enabled\": True},\n", + " }\n", + "\n", + "\n", + "# Pull readme\n", + "get_response = requests.get(\n", + " \"https://raw.githubusercontent.com/langchain-ai/langchain/master/README.md\"\n", + ")\n", + "readme = get_response.text\n", + "\n", + "# Split into chunks\n", + "splitter = MarkdownTextSplitter(\n", + " chunk_overlap=0,\n", + " chunk_size=50,\n", + ")\n", + "documents = splitter.split_text(readme)\n", + "\n", + "# Construct message\n", + "message = {\n", + " \"role\": \"user\",\n", + " \"content\": [\n", + " format_to_anthropic_documents(documents),\n", + " {\"type\": \"text\", \"text\": \"Give me a link to LangChain's tutorials.\"},\n", + " ],\n", + "}\n", + "\n", + "# Query LLM\n", + "llm = ChatAnthropic(model=\"claude-3-5-haiku-latest\")\n", + "response = llm.invoke([message])\n", + "\n", + "response.content" + ] + }, { "cell_type": "markdown", "id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3", @@ -342,7 +499,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.10.4" } }, "nbformat": 4,