mirror of
				https://github.com/hwchase17/langchain.git
				synced 2025-10-30 23:29:54 +00:00 
			
		
		
		
	Moved the following modules to new package langchain-community in a backwards compatible fashion: ``` mv langchain/langchain/adapters community/langchain_community mv langchain/langchain/callbacks community/langchain_community/callbacks mv langchain/langchain/chat_loaders community/langchain_community mv langchain/langchain/chat_models community/langchain_community mv langchain/langchain/document_loaders community/langchain_community mv langchain/langchain/docstore community/langchain_community mv langchain/langchain/document_transformers community/langchain_community mv langchain/langchain/embeddings community/langchain_community mv langchain/langchain/graphs community/langchain_community mv langchain/langchain/llms community/langchain_community mv langchain/langchain/memory/chat_message_histories community/langchain_community mv langchain/langchain/retrievers community/langchain_community mv langchain/langchain/storage community/langchain_community mv langchain/langchain/tools community/langchain_community mv langchain/langchain/utilities community/langchain_community mv langchain/langchain/vectorstores community/langchain_community mv langchain/langchain/agents/agent_toolkits community/langchain_community mv langchain/langchain/cache.py community/langchain_community mv langchain/langchain/adapters community/langchain_community mv langchain/langchain/callbacks community/langchain_community/callbacks mv langchain/langchain/chat_loaders community/langchain_community mv langchain/langchain/chat_models community/langchain_community mv langchain/langchain/document_loaders community/langchain_community mv langchain/langchain/docstore community/langchain_community mv langchain/langchain/document_transformers community/langchain_community mv langchain/langchain/embeddings community/langchain_community mv langchain/langchain/graphs community/langchain_community mv langchain/langchain/llms community/langchain_community mv langchain/langchain/memory/chat_message_histories community/langchain_community mv langchain/langchain/retrievers community/langchain_community mv langchain/langchain/storage community/langchain_community mv langchain/langchain/tools community/langchain_community mv langchain/langchain/utilities community/langchain_community mv langchain/langchain/vectorstores community/langchain_community mv langchain/langchain/agents/agent_toolkits community/langchain_community mv langchain/langchain/cache.py community/langchain_community ``` Moved the following to core ``` mv langchain/langchain/utils/json_schema.py core/langchain_core/utils mv langchain/langchain/utils/html.py core/langchain_core/utils mv langchain/langchain/utils/strings.py core/langchain_core/utils cat langchain/langchain/utils/env.py >> core/langchain_core/utils/env.py rm langchain/langchain/utils/env.py ``` See .scripts/community_split/script_integrations.sh for all changes
		
			
				
	
	
		
			352 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			352 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import re
 | |
| import warnings
 | |
| from typing import (
 | |
|     Any,
 | |
|     AsyncIterator,
 | |
|     Callable,
 | |
|     Dict,
 | |
|     Iterator,
 | |
|     List,
 | |
|     Mapping,
 | |
|     Optional,
 | |
| )
 | |
| 
 | |
| 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")
 | |
|     """Model name to use."""
 | |
| 
 | |
|     max_tokens_to_sample: int = Field(default=256, alias="max_tokens")
 | |
|     """Denotes the number of tokens to predict per generation."""
 | |
| 
 | |
|     temperature: Optional[float] = None
 | |
|     """A non-negative float that tunes the degree of randomness in generation."""
 | |
| 
 | |
|     top_k: Optional[int] = None
 | |
|     """Number of most likely tokens to consider at each step."""
 | |
| 
 | |
|     top_p: Optional[float] = None
 | |
|     """Total probability mass of tokens to consider at each step."""
 | |
| 
 | |
|     streaming: bool = False
 | |
|     """Whether to stream the results."""
 | |
| 
 | |
|     default_request_timeout: Optional[float] = None
 | |
|     """Timeout for requests to Anthropic Completion API. Default is 600 seconds."""
 | |
| 
 | |
|     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:
 | |
|         """Validate that api key and python package exists in environment."""
 | |
|         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"],
 | |
|             )
 | |
|             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"],
 | |
|             )
 | |
|             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]:
 | |
|         """Get the default parameters for calling 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]:
 | |
|         """Get the identifying parameters."""
 | |
|         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
 | |
| 
 | |
| 
 | |
| class Anthropic(LLM, _AnthropicCommon):
 | |
|     """Anthropic large language models.
 | |
| 
 | |
|     To use, you should have the ``anthropic`` python package installed, and the
 | |
|     environment variable ``ANTHROPIC_API_KEY`` set with your API key, or pass
 | |
|     it as a named parameter to the constructor.
 | |
| 
 | |
|     Example:
 | |
|         .. code-block:: python
 | |
| 
 | |
|             import anthropic
 | |
|             from langchain_community.llms import Anthropic
 | |
| 
 | |
|             model = Anthropic(model="<model_name>", anthropic_api_key="my-api-key")
 | |
| 
 | |
|             # Simplest invocation, automatically wrapped with HUMAN_PROMPT
 | |
|             # and AI_PROMPT.
 | |
|             response = model("What are the biggest risks facing humanity?")
 | |
| 
 | |
|             # Or if you want to use the chat mode, build a few-shot-prompt, or
 | |
|             # put words in the Assistant's mouth, use HUMAN_PROMPT and AI_PROMPT:
 | |
|             raw_prompt = "What are the biggest risks facing humanity?"
 | |
|             prompt = f"{anthropic.HUMAN_PROMPT} {prompt}{anthropic.AI_PROMPT}"
 | |
|             response = model(prompt)
 | |
|     """
 | |
| 
 | |
|     class Config:
 | |
|         """Configuration for this pydantic object."""
 | |
| 
 | |
|         allow_population_by_field_name = True
 | |
|         arbitrary_types_allowed = True
 | |
| 
 | |
|     @root_validator()
 | |
|     def raise_warning(cls, values: Dict) -> Dict:
 | |
|         """Raise warning that this class is deprecated."""
 | |
|         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:
 | |
|         """Return type of 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"""Call out to Anthropic's completion endpoint.
 | |
| 
 | |
|         Args:
 | |
|             prompt: The prompt to pass into the model.
 | |
|             stop: Optional list of stop words to use when generating.
 | |
| 
 | |
|         Returns:
 | |
|             The string generated by the model.
 | |
| 
 | |
|         Example:
 | |
|             .. code-block:: python
 | |
| 
 | |
|                 prompt = "What are the biggest risks facing humanity?"
 | |
|                 prompt = f"\n\nHuman: {prompt}\n\nAssistant:"
 | |
|                 response = model(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
 | |
| 
 | |
|     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:
 | |
|         """Call out to Anthropic's completion endpoint asynchronously."""
 | |
|         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"""Call Anthropic completion_stream and return the resulting generator.
 | |
| 
 | |
|         Args:
 | |
|             prompt: The prompt to pass into the model.
 | |
|             stop: Optional list of stop words to use when generating.
 | |
|         Returns:
 | |
|             A generator representing the stream of tokens from Anthropic.
 | |
|         Example:
 | |
|             .. code-block:: python
 | |
| 
 | |
|                 prompt = "Write a poem about a stream."
 | |
|                 prompt = f"\n\nHuman: {prompt}\n\nAssistant:"
 | |
|                 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)
 | |
|             yield chunk
 | |
|             if run_manager:
 | |
|                 run_manager.on_llm_new_token(chunk.text, chunk=chunk)
 | |
| 
 | |
|     async def _astream(
 | |
|         self,
 | |
|         prompt: str,
 | |
|         stop: Optional[List[str]] = None,
 | |
|         run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
 | |
|         **kwargs: Any,
 | |
|     ) -> AsyncIterator[GenerationChunk]:
 | |
|         r"""Call Anthropic completion_stream and return the resulting generator.
 | |
| 
 | |
|         Args:
 | |
|             prompt: The prompt to pass into the model.
 | |
|             stop: Optional list of stop words to use when generating.
 | |
|         Returns:
 | |
|             A generator representing the stream of tokens from Anthropic.
 | |
|         Example:
 | |
|             .. code-block:: python
 | |
|                 prompt = "Write a poem about a stream."
 | |
|                 prompt = f"\n\nHuman: {prompt}\n\nAssistant:"
 | |
|                 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)
 | |
|             yield chunk
 | |
|             if run_manager:
 | |
|                 await run_manager.on_llm_new_token(chunk.text, chunk=chunk)
 | |
| 
 | |
|     def get_num_tokens(self, text: str) -> int:
 | |
|         """Calculate number of tokens."""
 | |
|         if not self.count_tokens:
 | |
|             raise NameError("Please ensure the anthropic package is loaded")
 | |
|         return self.count_tokens(text)
 |