Skip to content

Commit 00e992a

Browse files
authored
feat(anthropic): web fetch beta (#32894)
Note: citations are broken until Anthropic fixes their API
1 parent 83d9385 commit 00e992a

File tree

5 files changed

+1638
-1089
lines changed

5 files changed

+1638
-1089
lines changed

docs/docs/integrations/chat/anthropic.ipynb

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -970,8 +970,8 @@
970970
"source": [
971971
"### In tool results (agentic RAG)\n",
972972
"\n",
973-
":::info Requires ``langchain-anthropic>=0.3.17``\n",
974-
"\n",
973+
":::info\n",
974+
"Requires ``langchain-anthropic>=0.3.17``\n",
975975
":::\n",
976976
"\n",
977977
"Claude supports a [search_result](https://docs.anthropic.com/en/docs/build-with-claude/search-results) content block representing citable results from queries against a knowledge base or other custom source. These content blocks can be passed to claude both top-line (as in the above example) and within a tool result. This allows Claude to cite elements of its response using the result of a tool call.\n",
@@ -1290,6 +1290,58 @@
12901290
"print(f\"Key Points: {result.key_points}\")"
12911291
]
12921292
},
1293+
{
1294+
"cell_type": "markdown",
1295+
"id": "c580c20a",
1296+
"metadata": {},
1297+
"source": [
1298+
"### Web fetching\n",
1299+
"\n",
1300+
"Claude can use a [web fetching tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-fetch-tool) to run searches and ground its responses with citations."
1301+
]
1302+
},
1303+
{
1304+
"cell_type": "markdown",
1305+
"id": "5cf6ad08",
1306+
"metadata": {},
1307+
"source": [
1308+
":::info\n",
1309+
"Web search tool is supported since ``langchain-anthropic>=0.3.20``\n",
1310+
":::"
1311+
]
1312+
},
1313+
{
1314+
"cell_type": "code",
1315+
"execution_count": null,
1316+
"id": "c4804be1",
1317+
"metadata": {},
1318+
"outputs": [],
1319+
"source": [
1320+
"from langchain_anthropic import ChatAnthropic\n",
1321+
"\n",
1322+
"llm = ChatAnthropic(\n",
1323+
" model=\"claude-3-5-haiku-latest\",\n",
1324+
" betas=[\"web-fetch-2025-09-10\"], # Enable web fetch beta\n",
1325+
")\n",
1326+
"\n",
1327+
"tool = {\"type\": \"web_fetch_20250910\", \"name\": \"web_fetch\", \"max_uses\": 3}\n",
1328+
"llm_with_tools = llm.bind_tools([tool])\n",
1329+
"\n",
1330+
"response = llm_with_tools.invoke(\n",
1331+
" \"Please analyze the content at https://example.com/article\"\n",
1332+
")"
1333+
]
1334+
},
1335+
{
1336+
"cell_type": "markdown",
1337+
"id": "088c41d0",
1338+
"metadata": {},
1339+
"source": [
1340+
":::warning\n",
1341+
"Note: you must add the `'web-fetch-2025-09-10'` beta header to use this tool.\n",
1342+
":::"
1343+
]
1344+
},
12931345
{
12941346
"cell_type": "markdown",
12951347
"id": "1478cdc6-2e52-4870-80f9-b4ddf88f2db2",
@@ -1299,14 +1351,14 @@
12991351
"\n",
13001352
"Claude can use a [code execution tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/code-execution-tool) to execute Python code in a sandboxed environment.\n",
13011353
"\n",
1302-
":::info Code execution is supported since ``langchain-anthropic>=0.3.14``\n",
1303-
"\n",
1354+
":::info\n",
1355+
"Code execution is supported since ``langchain-anthropic>=0.3.14``\n",
13041356
":::"
13051357
]
13061358
},
13071359
{
13081360
"cell_type": "code",
1309-
"execution_count": 1,
1361+
"execution_count": null,
13101362
"id": "2ce13632-a2da-439f-a429-f66481501630",
13111363
"metadata": {},
13121364
"outputs": [],
@@ -1315,7 +1367,7 @@
13151367
"\n",
13161368
"llm = ChatAnthropic(\n",
13171369
" model=\"claude-sonnet-4-20250514\",\n",
1318-
" betas=[\"code-execution-2025-05-22\"],\n",
1370+
" betas=[\"code-execution-2025-05-22\"], # Enable code execution beta\n",
13191371
")\n",
13201372
"\n",
13211373
"tool = {\"type\": \"code_execution_20250522\", \"name\": \"code_execution\"}\n",
@@ -1326,6 +1378,16 @@
13261378
")"
13271379
]
13281380
},
1381+
{
1382+
"cell_type": "markdown",
1383+
"id": "a6b5e15a",
1384+
"metadata": {},
1385+
"source": [
1386+
":::warning\n",
1387+
"Note: you must add the `'code_execution_20250522'` beta header to use this tool.\n",
1388+
":::"
1389+
]
1390+
},
13291391
{
13301392
"cell_type": "markdown",
13311393
"id": "24076f91-3a3d-4e53-9618-429888197061",
@@ -1404,14 +1466,14 @@
14041466
"\n",
14051467
"Claude can use a [MCP connector tool](https://docs.anthropic.com/en/docs/agents-and-tools/mcp-connector) for model-generated calls to remote MCP servers.\n",
14061468
"\n",
1407-
":::info Remote MCP is supported since ``langchain-anthropic>=0.3.14``\n",
1408-
"\n",
1469+
":::info\n",
1470+
"Remote MCP is supported since ``langchain-anthropic>=0.3.14``\n",
14091471
":::"
14101472
]
14111473
},
14121474
{
14131475
"cell_type": "code",
1414-
"execution_count": 1,
1476+
"execution_count": null,
14151477
"id": "22fc4a89-e6d8-4615-96cb-2e117349aebf",
14161478
"metadata": {},
14171479
"outputs": [],
@@ -1423,17 +1485,17 @@
14231485
" \"type\": \"url\",\n",
14241486
" \"url\": \"https://mcp.deepwiki.com/mcp\",\n",
14251487
" \"name\": \"deepwiki\",\n",
1426-
" \"tool_configuration\": { # optional configuration\n",
1488+
" \"tool_configuration\": { # Optional configuration\n",
14271489
" \"enabled\": True,\n",
14281490
" \"allowed_tools\": [\"ask_question\"],\n",
14291491
" },\n",
1430-
" \"authorization_token\": \"PLACEHOLDER\", # optional authorization\n",
1492+
" \"authorization_token\": \"PLACEHOLDER\", # Optional authorization\n",
14311493
" }\n",
14321494
"]\n",
14331495
"\n",
14341496
"llm = ChatAnthropic(\n",
14351497
" model=\"claude-sonnet-4-20250514\",\n",
1436-
" betas=[\"mcp-client-2025-04-04\"],\n",
1498+
" betas=[\"mcp-client-2025-04-04\"], # Enable MCP beta\n",
14371499
" mcp_servers=mcp_servers,\n",
14381500
")\n",
14391501
"\n",
@@ -1443,6 +1505,16 @@
14431505
")"
14441506
]
14451507
},
1508+
{
1509+
"cell_type": "markdown",
1510+
"id": "0d6d7197",
1511+
"metadata": {},
1512+
"source": [
1513+
":::warning\n",
1514+
"Note: you must add the `'mcp-client-2025-04-04'` beta header to use this tool.\n",
1515+
":::"
1516+
]
1517+
},
14461518
{
14471519
"cell_type": "markdown",
14481520
"id": "2fd5d545-a40d-42b1-ad0c-0a79e2536c9b",

libs/partners/anthropic/langchain_anthropic/chat_models.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class AnthropicTool(TypedDict):
7171

7272

7373
def _is_builtin_tool(tool: Any) -> bool:
74+
"""Check if a tool is a built-in Anthropic tool.
75+
76+
https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview
77+
"""
7478
if not isinstance(tool, dict):
7579
return False
7680

@@ -83,6 +87,7 @@ def _is_builtin_tool(tool: Any) -> bool:
8387
"computer_",
8488
"bash_",
8589
"web_search_",
90+
"web_fetch_",
8691
"code_execution_",
8792
]
8893
return any(tool_type.startswith(prefix) for prefix in _builtin_tool_prefixes)
@@ -277,16 +282,7 @@ def _format_data_content_block(block: dict) -> dict:
277282
def _format_messages(
278283
messages: Sequence[BaseMessage],
279284
) -> tuple[Union[str, list[dict], None], list[dict]]:
280-
"""Format messages for anthropic."""
281-
"""
282-
[
283-
{
284-
"role": _message_type_lookups[m.type],
285-
"content": [_AnthropicMessageContent(text=m.content).model_dump()],
286-
}
287-
for m in messages
288-
]
289-
"""
285+
"""Format messages for Anthropic's API."""
290286
system: Union[str, list[dict], None] = None
291287
formatted_messages: list[dict] = []
292288
merged_messages = _merge_messages(messages)
@@ -440,6 +436,7 @@ def _format_messages(
440436
"code_execution_tool_result",
441437
"mcp_tool_result",
442438
"web_search_tool_result",
439+
"web_fetch_tool_result",
443440
):
444441
content.append(
445442
{
@@ -452,6 +449,7 @@ def _format_messages(
452449
"tool_use_id",
453450
"is_error", # for mcp_tool_result
454451
"cache_control",
452+
"retrieved_at", # for web_fetch_tool_result
455453
)
456454
},
457455
)
@@ -1137,6 +1135,24 @@ def get_weather(location: str) -> str:
11371135
"How do I update a web app to TypeScript 5.5?"
11381136
)
11391137
1138+
.. dropdown:: Web fetch (beta)
1139+
1140+
.. code-block:: python
1141+
1142+
from langchain_anthropic import ChatAnthropic
1143+
1144+
llm = ChatAnthropic(
1145+
model="claude-3-5-haiku-latest",
1146+
betas=["web-fetch-2025-09-10"], # Enable web fetch beta
1147+
)
1148+
1149+
tool = {"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 3}
1150+
llm_with_tools = llm.bind_tools([tool])
1151+
1152+
response = llm_with_tools.invoke(
1153+
"Please analyze the content at https://example.com/article"
1154+
)
1155+
11401156
.. dropdown:: Code execution
11411157
11421158
.. code-block:: python
@@ -2232,6 +2248,7 @@ def _make_message_chunk_from_anthropic_event(
22322248
"mcp_tool_result",
22332249
"server_tool_use", # Server-side tool usage
22342250
"web_search_tool_result", # Built-in web search results
2251+
"web_fetch_tool_result", # Built-in web fetch results,
22352252
)
22362253
):
22372254
if coerce_content_to_string:

libs/partners/anthropic/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ authors = []
77
license = { text = "MIT" }
88
requires-python = ">=3.9"
99
dependencies = [
10-
"anthropic<1,>=0.64.0",
11-
"langchain-core<1.0.0,>=0.3.74",
10+
"anthropic<1,>=0.67.0",
11+
"langchain-core<1.0.0,>=0.3.76",
1212
"pydantic<3.0.0,>=2.7.4",
1313
]
1414
name = "langchain-anthropic"

0 commit comments

Comments
 (0)