Source code for langchain_community.llms.anthropic

import re
import warnings
from typing import (
    Any,
    AsyncIterator,
    Callable,
    Dict,
    Iterator,
    List,
    Mapping,
    Optional,
)

from langchain_core._api.deprecation import deprecated
from langchain_core.callbacks import (
    AsyncCallbackManagerForLLMRun,
    CallbackManagerForLLMRun,
)
from langchain_core.language_models import BaseLanguageModel
from langchain_core.language_models.llms import LLM
from langchain_core.outputs import GenerationChunk
from langchain_core.prompt_values import PromptValue
from langchain_core.pydantic_v1 import Field, SecretStr, root_validator
from langchain_core.utils import (
    check_package_version,
    get_from_dict_or_env,
    get_pydantic_field_names,
)
from langchain_core.utils.utils import build_extra_kwargs, convert_to_secret_str


class _AnthropicCommon(BaseLanguageModel):
    client: Any = None  #: :meta private:
    async_client: Any = None  #: :meta private:
    model: str = Field(default="claude-2", alias="model_name")
    """要使用的模型名称。"""

    max_tokens_to_sample: int = Field(default=256, alias="max_tokens")
    """表示每代要预测的令牌数量。"""

    temperature: Optional[float] = None
    """一个非负浮点数,用于调整生成过程中的随机程度。"""

    top_k: Optional[int] = None
    """每个步骤考虑的最有可能的令牌数量。"""

    top_p: Optional[float] = None
    """每一步需要考虑的标记的总概率质量。"""

    streaming: bool = False
    """是否流式传输结果。"""

    default_request_timeout: Optional[float] = None
    """请求Anthropic Completion API的超时时间。默认为600秒。"""

    max_retries: int = 2
    """发送到Anthropic Completion API的请求允许的重试次数。"""

    anthropic_api_url: Optional[str] = None

    anthropic_api_key: Optional[SecretStr] = None

    HUMAN_PROMPT: Optional[str] = None
    AI_PROMPT: Optional[str] = None
    count_tokens: Optional[Callable[[str], int]] = None
    model_kwargs: Dict[str, Any] = Field(default_factory=dict)

    @root_validator(pre=True)
    def build_extra(cls, values: Dict) -> Dict:
        extra = values.get("model_kwargs", {})
        all_required_field_names = get_pydantic_field_names(cls)
        values["model_kwargs"] = build_extra_kwargs(
            extra, values, all_required_field_names
        )
        return values

    @root_validator()
    def validate_environment(cls, values: Dict) -> Dict:
        """验证环境中是否存在API密钥和Python包。"""
        values["anthropic_api_key"] = convert_to_secret_str(
            get_from_dict_or_env(values, "anthropic_api_key", "ANTHROPIC_API_KEY")
        )
        # Get custom api url from environment.
        values["anthropic_api_url"] = get_from_dict_or_env(
            values,
            "anthropic_api_url",
            "ANTHROPIC_API_URL",
            default="https://api.anthropic.com",
        )

        try:
            import anthropic

            check_package_version("anthropic", gte_version="0.3")
            values["client"] = anthropic.Anthropic(
                base_url=values["anthropic_api_url"],
                api_key=values["anthropic_api_key"].get_secret_value(),
                timeout=values["default_request_timeout"],
                max_retries=values["max_retries"],
            )
            values["async_client"] = anthropic.AsyncAnthropic(
                base_url=values["anthropic_api_url"],
                api_key=values["anthropic_api_key"].get_secret_value(),
                timeout=values["default_request_timeout"],
                max_retries=values["max_retries"],
            )
            values["HUMAN_PROMPT"] = anthropic.HUMAN_PROMPT
            values["AI_PROMPT"] = anthropic.AI_PROMPT
            values["count_tokens"] = values["client"].count_tokens

        except ImportError:
            raise ImportError(
                "Could not import anthropic python package. "
                "Please it install it with `pip install anthropic`."
            )
        return values

    @property
    def _default_params(self) -> Mapping[str, Any]:
        """获取调用Anthropic API的默认参数。"""
        d = {
            "max_tokens_to_sample": self.max_tokens_to_sample,
            "model": self.model,
        }
        if self.temperature is not None:
            d["temperature"] = self.temperature
        if self.top_k is not None:
            d["top_k"] = self.top_k
        if self.top_p is not None:
            d["top_p"] = self.top_p
        return {**d, **self.model_kwargs}

    @property
    def _identifying_params(self) -> Mapping[str, Any]:
        """获取识别参数。"""
        return {**{}, **self._default_params}

    def _get_anthropic_stop(self, stop: Optional[List[str]] = None) -> List[str]:
        if not self.HUMAN_PROMPT or not self.AI_PROMPT:
            raise NameError("Please ensure the anthropic package is loaded")

        if stop is None:
            stop = []

        # Never want model to invent new turns of Human / Assistant dialog.
        stop.extend([self.HUMAN_PROMPT])

        return stop


[docs]@deprecated( since="0.0.28", removal="0.3", alternative_import="langchain_anthropic.AnthropicLLM", ) class Anthropic(LLM, _AnthropicCommon): """人类学大型语言模型。 要使用,您应该安装``anthropic`` python包,并设置环境变量``ANTHROPIC_API_KEY``为您的API密钥,或将其作为命名参数传递给构造函数。 示例: .. code-block:: python import anthropic from langchain_community.llms import Anthropic model = Anthropic(model="<model_name>", anthropic_api_key="my-api-key") # 最简单的调用方式,自动包装了HUMAN_PROMPT和AI_PROMPT。 response = model.invoke("What are the biggest risks facing humanity?") # 或者如果您想使用聊天模式,构建一个few-shot-prompt,或者让Assistant说话,使用HUMAN_PROMPT和AI_PROMPT: raw_prompt = "What are the biggest risks facing humanity?" prompt = f"{anthropic.HUMAN_PROMPT} {prompt}{anthropic.AI_PROMPT}" response = model.invoke(prompt)""" class Config: """此pydantic对象的配置。""" allow_population_by_field_name = True arbitrary_types_allowed = True @root_validator() def raise_warning(cls, values: Dict) -> Dict: """发出警告,说明这个类已经被弃用。""" warnings.warn( "This Anthropic LLM is deprecated. " "Please use `from langchain_community.chat_models import ChatAnthropic` " "instead" ) return values @property def _llm_type(self) -> str: """llm的返回类型。""" return "anthropic-llm" def _wrap_prompt(self, prompt: str) -> str: if not self.HUMAN_PROMPT or not self.AI_PROMPT: raise NameError("Please ensure the anthropic package is loaded") if prompt.startswith(self.HUMAN_PROMPT): return prompt # Already wrapped. # Guard against common errors in specifying wrong number of newlines. corrected_prompt, n_subs = re.subn(r"^\n*Human:", self.HUMAN_PROMPT, prompt) if n_subs == 1: return corrected_prompt # As a last resort, wrap the prompt ourselves to emulate instruct-style. return f"{self.HUMAN_PROMPT} {prompt}{self.AI_PROMPT} Sure, here you go:\n" def _call( self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> str: r"""调用Anthropic的完成端点。 参数: prompt: 传递给模型的提示。 stop: 生成时可选的停止词列表。 返回: 模型生成的字符串。 示例: .. code-block:: python prompt = "What are the biggest risks facing humanity?" prompt = f"\n\nHuman: {prompt}\n\nAssistant:" response = model.invoke(prompt) """ if self.streaming: completion = "" for chunk in self._stream( prompt=prompt, stop=stop, run_manager=run_manager, **kwargs ): completion += chunk.text return completion stop = self._get_anthropic_stop(stop) params = {**self._default_params, **kwargs} response = self.client.completions.create( prompt=self._wrap_prompt(prompt), stop_sequences=stop, **params, ) return response.completion
[docs] def convert_prompt(self, prompt: PromptValue) -> str: return self._wrap_prompt(prompt.to_string())
async def _acall( self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, **kwargs: Any, ) -> str: """异步调用Anthropic的完成端点。""" if self.streaming: completion = "" async for chunk in self._astream( prompt=prompt, stop=stop, run_manager=run_manager, **kwargs ): completion += chunk.text return completion stop = self._get_anthropic_stop(stop) params = {**self._default_params, **kwargs} response = await self.async_client.completions.create( prompt=self._wrap_prompt(prompt), stop_sequences=stop, **params, ) return response.completion def _stream( self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any, ) -> Iterator[GenerationChunk]: r"""调用Anthropic的completion_stream并返回生成的生成器。 参数: prompt: 传递给模型的提示。 stop: 生成时使用的可选停止词列表。 返回: 代表Anthropic令牌流的生成器。 示例: .. code-block:: python prompt = "写一首关于小溪的诗。" prompt = f"\n\n人类: {prompt}\n\n助手:" generator = anthropic.stream(prompt) for token in generator: yield token """ stop = self._get_anthropic_stop(stop) params = {**self._default_params, **kwargs} for token in self.client.completions.create( prompt=self._wrap_prompt(prompt), stop_sequences=stop, stream=True, **params ): chunk = GenerationChunk(text=token.completion) if run_manager: run_manager.on_llm_new_token(chunk.text, chunk=chunk) yield chunk async def _astream( self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, **kwargs: Any, ) -> AsyncIterator[GenerationChunk]: r"""调用Anthropic的completion_stream并返回生成的生成器。 参数: prompt: 传递给模型的提示。 stop: 生成时使用的可选停止词列表。 返回: 代表来自Anthropic的令牌流的生成器。 示例: .. code-block:: python prompt = "写一首关于小溪的诗。" prompt = f"\n\n人类:{prompt}\n\n助手:" generator = anthropic.stream(prompt) for token in generator: yield token """ stop = self._get_anthropic_stop(stop) params = {**self._default_params, **kwargs} async for token in await self.async_client.completions.create( prompt=self._wrap_prompt(prompt), stop_sequences=stop, stream=True, **params, ): chunk = GenerationChunk(text=token.completion) if run_manager: await run_manager.on_llm_new_token(chunk.text, chunk=chunk) yield chunk
[docs] def get_num_tokens(self, text: str) -> int: """计算令牌数量。""" if not self.count_tokens: raise NameError("Please ensure the anthropic package is loaded") return self.count_tokens(text)