From dc396835ed283b5e7dd0bf2b306505b986b34554 Mon Sep 17 00:00:00 2001 From: kiarina Date: Wed, 3 Jul 2024 04:16:20 +0900 Subject: [PATCH] langchain_anthropic: add stop_reason in ChatAnthropic stream result (#23689) `ChatAnthropic` can get `stop_reason` from the resulting `AIMessage` in `invoke` and `ainvoke`, but not in `stream` and `astream`. This is a different behavior from `ChatOpenAI`. It is possible to get `stop_reason` from `stream` as well, since it is needed to determine the next action after the LLM call. This would be easier to handle in situations where only `stop_reason` is needed. - Issue: NA - Dependencies: NA - Twitter handle: https://x.com/kiarina37 --- libs/partners/anthropic/langchain_anthropic/chat_models.py | 6 +++++- .../anthropic/tests/integration_tests/test_chat_models.py | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libs/partners/anthropic/langchain_anthropic/chat_models.py b/libs/partners/anthropic/langchain_anthropic/chat_models.py index d24fab015d9..ce553dc468f 100644 --- a/libs/partners/anthropic/langchain_anthropic/chat_models.py +++ b/libs/partners/anthropic/langchain_anthropic/chat_models.py @@ -518,7 +518,7 @@ class ChatAnthropic(BaseChatModel): anthropic_api_url: Optional[str] = Field(None, alias="base_url") """Base URL for API requests. Only specify if using a proxy or service emulator. - + If a value isn't passed in and environment variable ANTHROPIC_BASE_URL is set, value will be read from there. """ @@ -1139,6 +1139,10 @@ def _make_message_chunk_from_anthropic_event( output_tokens=output_tokens, total_tokens=output_tokens, ), + response_metadata={ + "stop_reason": event.delta.stop_reason, + "stop_sequence": event.delta.stop_sequence, + }, ) else: pass diff --git a/libs/partners/anthropic/tests/integration_tests/test_chat_models.py b/libs/partners/anthropic/tests/integration_tests/test_chat_models.py index 198278fed87..78b0f2ead83 100644 --- a/libs/partners/anthropic/tests/integration_tests/test_chat_models.py +++ b/libs/partners/anthropic/tests/integration_tests/test_chat_models.py @@ -57,6 +57,8 @@ def test_stream() -> None: full.usage_metadata["input_tokens"] + full.usage_metadata["output_tokens"] == full.usage_metadata["total_tokens"] ) + assert "stop_reason" in full.response_metadata + assert "stop_sequence" in full.response_metadata async def test_astream() -> None: @@ -91,6 +93,8 @@ async def test_astream() -> None: full.usage_metadata["input_tokens"] + full.usage_metadata["output_tokens"] == full.usage_metadata["total_tokens"] ) + assert "stop_reason" in full.response_metadata + assert "stop_sequence" in full.response_metadata # test usage metadata can be excluded model = ChatAnthropic(model_name=MODEL_NAME, stream_usage=False) # type: ignore[call-arg]