langchain 0.2.11__py3-none-any.whl → 0.2.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. langchain/agents/agent.py +5 -9
  2. langchain/agents/agent_toolkits/vectorstore/base.py +114 -2
  3. langchain/agents/agent_toolkits/vectorstore/toolkit.py +0 -6
  4. langchain/agents/chat/output_parser.py +2 -2
  5. langchain/agents/initialize.py +1 -1
  6. langchain/agents/loading.py +2 -2
  7. langchain/agents/mrkl/base.py +1 -1
  8. langchain/agents/openai_assistant/base.py +2 -2
  9. langchain/agents/openai_functions_agent/base.py +1 -1
  10. langchain/agents/openai_functions_multi_agent/base.py +1 -1
  11. langchain/agents/output_parsers/react_json_single_input.py +2 -2
  12. langchain/agents/structured_chat/output_parser.py +2 -2
  13. langchain/chains/__init__.py +1 -0
  14. langchain/chains/api/base.py +121 -1
  15. langchain/chains/base.py +0 -2
  16. langchain/chains/combine_documents/map_reduce.py +2 -4
  17. langchain/chains/combine_documents/map_rerank.py +4 -6
  18. langchain/chains/combine_documents/reduce.py +1 -4
  19. langchain/chains/combine_documents/refine.py +2 -4
  20. langchain/chains/combine_documents/stuff.py +12 -4
  21. langchain/chains/conversation/base.py +2 -4
  22. langchain/chains/conversational_retrieval/base.py +4 -6
  23. langchain/chains/elasticsearch_database/base.py +16 -20
  24. langchain/chains/example_generator.py +3 -4
  25. langchain/chains/flare/base.py +1 -1
  26. langchain/chains/hyde/base.py +1 -4
  27. langchain/chains/llm.py +2 -4
  28. langchain/chains/llm_checker/base.py +12 -4
  29. langchain/chains/llm_math/base.py +2 -4
  30. langchain/chains/llm_summarization_checker/base.py +12 -4
  31. langchain/chains/loading.py +17 -0
  32. langchain/chains/mapreduce.py +12 -4
  33. langchain/chains/natbot/base.py +2 -4
  34. langchain/chains/openai_functions/__init__.py +2 -0
  35. langchain/chains/openai_functions/citation_fuzzy_match.py +54 -1
  36. langchain/chains/openai_functions/openapi.py +88 -1
  37. langchain/chains/openai_functions/qa_with_structure.py +19 -0
  38. langchain/chains/openai_functions/tagging.py +81 -0
  39. langchain/chains/qa_with_sources/base.py +21 -4
  40. langchain/chains/qa_with_sources/loading.py +16 -0
  41. langchain/chains/query_constructor/base.py +8 -2
  42. langchain/chains/query_constructor/schema.py +0 -2
  43. langchain/chains/question_answering/chain.py +15 -0
  44. langchain/chains/retrieval_qa/base.py +30 -6
  45. langchain/chains/router/base.py +1 -4
  46. langchain/chains/router/embedding_router.py +1 -4
  47. langchain/chains/router/llm_router.py +76 -1
  48. langchain/chains/router/multi_prompt.py +76 -1
  49. langchain/chains/sequential.py +3 -7
  50. langchain/chains/structured_output/base.py +1 -1
  51. langchain/chat_models/base.py +26 -3
  52. langchain/evaluation/agents/trajectory_eval_chain.py +3 -6
  53. langchain/evaluation/comparison/eval_chain.py +2 -4
  54. langchain/evaluation/criteria/eval_chain.py +2 -4
  55. langchain/evaluation/embedding_distance/base.py +3 -4
  56. langchain/evaluation/parsing/json_schema.py +1 -1
  57. langchain/evaluation/qa/eval_chain.py +2 -7
  58. langchain/evaluation/schema.py +8 -8
  59. langchain/evaluation/scoring/eval_chain.py +2 -4
  60. langchain/evaluation/string_distance/base.py +7 -6
  61. langchain/hub.py +60 -26
  62. langchain/indexes/vectorstore.py +3 -7
  63. langchain/memory/buffer.py +2 -2
  64. langchain/memory/entity.py +0 -2
  65. langchain/memory/summary.py +12 -2
  66. langchain/memory/summary_buffer.py +2 -2
  67. langchain/output_parsers/combining.py +2 -2
  68. langchain/output_parsers/enum.py +2 -2
  69. langchain/output_parsers/fix.py +4 -5
  70. langchain/output_parsers/retry.py +3 -3
  71. langchain/retrievers/contextual_compression.py +0 -2
  72. langchain/retrievers/document_compressors/base.py +0 -2
  73. langchain/retrievers/document_compressors/chain_filter.py +1 -1
  74. langchain/retrievers/document_compressors/cohere_rerank.py +2 -4
  75. langchain/retrievers/document_compressors/cross_encoder_rerank.py +1 -4
  76. langchain/retrievers/document_compressors/embeddings_filter.py +3 -4
  77. langchain/retrievers/document_compressors/listwise_rerank.py +1 -1
  78. langchain/retrievers/multi_query.py +4 -2
  79. langchain/retrievers/re_phraser.py +1 -1
  80. langchain/retrievers/self_query/base.py +11 -3
  81. langchain/retrievers/time_weighted_retriever.py +0 -2
  82. {langchain-0.2.11.dist-info → langchain-0.2.13.dist-info}/METADATA +2 -2
  83. {langchain-0.2.11.dist-info → langchain-0.2.13.dist-info}/RECORD +86 -86
  84. {langchain-0.2.11.dist-info → langchain-0.2.13.dist-info}/LICENSE +0 -0
  85. {langchain-0.2.11.dist-info → langchain-0.2.13.dist-info}/WHEEL +0 -0
  86. {langchain-0.2.11.dist-info → langchain-0.2.13.dist-info}/entry_points.txt +0 -0
@@ -2,12 +2,13 @@
2
2
 
3
3
  from typing import Any, Dict, List, Optional, Tuple
4
4
 
5
+ from langchain_core._api import deprecated
5
6
  from langchain_core.callbacks import Callbacks
6
7
  from langchain_core.documents import Document
7
8
  from langchain_core.language_models import LanguageModelLike
8
9
  from langchain_core.output_parsers import BaseOutputParser, StrOutputParser
9
10
  from langchain_core.prompts import BasePromptTemplate, format_document
10
- from langchain_core.pydantic_v1 import Extra, Field, root_validator
11
+ from langchain_core.pydantic_v1 import Field, root_validator
11
12
  from langchain_core.runnables import Runnable, RunnablePassthrough
12
13
 
13
14
  from langchain.chains.combine_documents.base import (
@@ -95,6 +96,15 @@ def create_stuff_documents_chain(
95
96
  ).with_config(run_name="stuff_documents_chain")
96
97
 
97
98
 
99
+ @deprecated(
100
+ since="0.2.13",
101
+ removal="1.0",
102
+ message=(
103
+ "This class is deprecated. Use the `create_stuff_documents_chain` constructor "
104
+ "instead. See migration guide here: "
105
+ "https://python.langchain.com/v0.2/docs/versions/migrating_chains/stuff_docs_chain/" # noqa: E501
106
+ ),
107
+ )
98
108
  class StuffDocumentsChain(BaseCombineDocumentsChain):
99
109
  """Chain that combines documents by stuffing into context.
100
110
 
@@ -147,10 +157,8 @@ class StuffDocumentsChain(BaseCombineDocumentsChain):
147
157
  """The string with which to join the formatted documents"""
148
158
 
149
159
  class Config:
150
- """Configuration for this pydantic object."""
151
-
152
- extra = Extra.forbid
153
160
  arbitrary_types_allowed = True
161
+ extra = "forbid"
154
162
 
155
163
  @root_validator(pre=True)
156
164
  def get_default_document_variable_name(cls, values: Dict) -> Dict:
@@ -5,7 +5,7 @@ from typing import Dict, List
5
5
  from langchain_core._api import deprecated
6
6
  from langchain_core.memory import BaseMemory
7
7
  from langchain_core.prompts import BasePromptTemplate
8
- from langchain_core.pydantic_v1 import Extra, Field, root_validator
8
+ from langchain_core.pydantic_v1 import Field, root_validator
9
9
 
10
10
  from langchain.chains.conversation.prompt import PROMPT
11
11
  from langchain.chains.llm import LLMChain
@@ -111,10 +111,8 @@ class ConversationChain(LLMChain):
111
111
  output_key: str = "response" #: :meta private:
112
112
 
113
113
  class Config:
114
- """Configuration for this pydantic object."""
115
-
116
- extra = Extra.forbid
117
114
  arbitrary_types_allowed = True
115
+ extra = "forbid"
118
116
 
119
117
  @classmethod
120
118
  def is_lc_serializable(cls) -> bool:
@@ -18,7 +18,7 @@ from langchain_core.documents import Document
18
18
  from langchain_core.language_models import BaseLanguageModel
19
19
  from langchain_core.messages import BaseMessage
20
20
  from langchain_core.prompts import BasePromptTemplate
21
- from langchain_core.pydantic_v1 import BaseModel, Extra, Field, root_validator
21
+ from langchain_core.pydantic_v1 import BaseModel, Field, root_validator
22
22
  from langchain_core.retrievers import BaseRetriever
23
23
  from langchain_core.runnables import RunnableConfig
24
24
  from langchain_core.vectorstores import VectorStore
@@ -97,11 +97,9 @@ class BaseConversationalRetrievalChain(Chain):
97
97
  are found for the question. """
98
98
 
99
99
  class Config:
100
- """Configuration for this pydantic object."""
101
-
102
- extra = Extra.forbid
103
- arbitrary_types_allowed = True
104
100
  allow_population_by_field_name = True
101
+ arbitrary_types_allowed = True
102
+ extra = "forbid"
105
103
 
106
104
  @property
107
105
  def input_keys(self) -> List[str]:
@@ -445,7 +443,7 @@ class ConversationalRetrievalChain(BaseConversationalRetrievalChain):
445
443
  combine_docs_chain_kwargs: Parameters to pass as kwargs to `load_qa_chain`
446
444
  when constructing the combine_docs_chain.
447
445
  callbacks: Callbacks to pass to all subchains.
448
- **kwargs: Additional parameters to pass when initializing
446
+ kwargs: Additional parameters to pass when initializing
449
447
  ConversationalRetrievalChain
450
448
  """
451
449
  combine_docs_chain_kwargs = combine_docs_chain_kwargs or {}
@@ -6,14 +6,14 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional
6
6
 
7
7
  from langchain_core.callbacks import CallbackManagerForChainRun
8
8
  from langchain_core.language_models import BaseLanguageModel
9
- from langchain_core.output_parsers import BaseLLMOutputParser
9
+ from langchain_core.output_parsers import BaseOutputParser, StrOutputParser
10
10
  from langchain_core.output_parsers.json import SimpleJsonOutputParser
11
11
  from langchain_core.prompts import BasePromptTemplate
12
- from langchain_core.pydantic_v1 import Extra, root_validator
12
+ from langchain_core.pydantic_v1 import root_validator
13
+ from langchain_core.runnables import Runnable
13
14
 
14
15
  from langchain.chains.base import Chain
15
16
  from langchain.chains.elasticsearch_database.prompts import ANSWER_PROMPT, DSL_PROMPT
16
- from langchain.chains.llm import LLMChain
17
17
 
18
18
  if TYPE_CHECKING:
19
19
  from elasticsearch import Elasticsearch
@@ -35,9 +35,9 @@ class ElasticsearchDatabaseChain(Chain):
35
35
  db_chain = ElasticsearchDatabaseChain.from_llm(OpenAI(), database)
36
36
  """
37
37
 
38
- query_chain: LLMChain
38
+ query_chain: Runnable
39
39
  """Chain for creating the ES query."""
40
- answer_chain: LLMChain
40
+ answer_chain: Runnable
41
41
  """Chain for answering the user question."""
42
42
  database: Any
43
43
  """Elasticsearch database to connect to of type elasticsearch.Elasticsearch."""
@@ -52,10 +52,8 @@ class ElasticsearchDatabaseChain(Chain):
52
52
  """Whether or not to return the intermediate steps along with the final answer."""
53
53
 
54
54
  class Config:
55
- """Configuration for this pydantic object."""
56
-
57
- extra = Extra.forbid
58
55
  arbitrary_types_allowed = True
56
+ extra = "forbid"
59
57
 
60
58
  @root_validator(pre=False, skip_on_failure=True)
61
59
  def validate_indices(cls, values: dict) -> dict:
@@ -137,9 +135,9 @@ class ElasticsearchDatabaseChain(Chain):
137
135
  intermediate_steps: List = []
138
136
  try:
139
137
  intermediate_steps.append(query_inputs) # input: es generation
140
- es_cmd = self.query_chain.run(
141
- callbacks=_run_manager.get_child(),
142
- **query_inputs,
138
+ es_cmd = self.query_chain.invoke(
139
+ query_inputs,
140
+ config={"callbacks": _run_manager.get_child()},
143
141
  )
144
142
 
145
143
  _run_manager.on_text(es_cmd, color="green", verbose=self.verbose)
@@ -156,9 +154,9 @@ class ElasticsearchDatabaseChain(Chain):
156
154
  _run_manager.on_text("\nAnswer:", verbose=self.verbose)
157
155
  answer_inputs: dict = {"data": result, "input": input_text}
158
156
  intermediate_steps.append(answer_inputs) # input: final answer
159
- final_result = self.answer_chain.run(
160
- callbacks=_run_manager.get_child(),
161
- **answer_inputs,
157
+ final_result = self.answer_chain.invoke(
158
+ answer_inputs,
159
+ config={"callbacks": _run_manager.get_child()},
162
160
  )
163
161
 
164
162
  intermediate_steps.append(final_result) # output: final answer
@@ -185,7 +183,7 @@ class ElasticsearchDatabaseChain(Chain):
185
183
  *,
186
184
  query_prompt: Optional[BasePromptTemplate] = None,
187
185
  answer_prompt: Optional[BasePromptTemplate] = None,
188
- query_output_parser: Optional[BaseLLMOutputParser] = None,
186
+ query_output_parser: Optional[BaseOutputParser] = None,
189
187
  **kwargs: Any,
190
188
  ) -> ElasticsearchDatabaseChain:
191
189
  """Convenience method to construct ElasticsearchDatabaseChain from an LLM.
@@ -197,15 +195,13 @@ class ElasticsearchDatabaseChain(Chain):
197
195
  answer_prompt: The prompt to use for answering user question given data.
198
196
  query_output_parser: The output parser to use for parsing model-generated
199
197
  ES query. Defaults to SimpleJsonOutputParser.
200
- **kwargs: Additional arguments to pass to the constructor.
198
+ kwargs: Additional arguments to pass to the constructor.
201
199
  """
202
200
  query_prompt = query_prompt or DSL_PROMPT
203
201
  query_output_parser = query_output_parser or SimpleJsonOutputParser()
204
- query_chain = LLMChain(
205
- llm=llm, prompt=query_prompt, output_parser=query_output_parser
206
- )
202
+ query_chain = query_prompt | llm | query_output_parser
207
203
  answer_prompt = answer_prompt or ANSWER_PROMPT
208
- answer_chain = LLMChain(llm=llm, prompt=answer_prompt)
204
+ answer_chain = answer_prompt | llm | StrOutputParser()
209
205
  return cls(
210
206
  query_chain=query_chain,
211
207
  answer_chain=answer_chain,
@@ -1,11 +1,10 @@
1
1
  from typing import List
2
2
 
3
3
  from langchain_core.language_models import BaseLanguageModel
4
+ from langchain_core.output_parsers import StrOutputParser
4
5
  from langchain_core.prompts.few_shot import FewShotPromptTemplate
5
6
  from langchain_core.prompts.prompt import PromptTemplate
6
7
 
7
- from langchain.chains.llm import LLMChain
8
-
9
8
  TEST_GEN_TEMPLATE_SUFFIX = "Add another example."
10
9
 
11
10
 
@@ -19,5 +18,5 @@ def generate_example(
19
18
  input_variables=[],
20
19
  example_prompt=prompt_template,
21
20
  )
22
- chain = LLMChain(llm=llm, prompt=prompt)
23
- return chain.predict()
21
+ chain = prompt | llm | StrOutputParser()
22
+ return chain.invoke({})
@@ -245,7 +245,7 @@ class FlareChain(Chain):
245
245
  Args:
246
246
  llm: Language model to use.
247
247
  max_generation_len: Maximum length of the generated response.
248
- **kwargs: Additional arguments to pass to the constructor.
248
+ kwargs: Additional arguments to pass to the constructor.
249
249
 
250
250
  Returns:
251
251
  FlareChain class with the given language model.
@@ -12,7 +12,6 @@ from langchain_core.callbacks import CallbackManagerForChainRun
12
12
  from langchain_core.embeddings import Embeddings
13
13
  from langchain_core.language_models import BaseLanguageModel
14
14
  from langchain_core.prompts import BasePromptTemplate
15
- from langchain_core.pydantic_v1 import Extra
16
15
 
17
16
  from langchain.chains.base import Chain
18
17
  from langchain.chains.hyde.prompts import PROMPT_MAP
@@ -29,10 +28,8 @@ class HypotheticalDocumentEmbedder(Chain, Embeddings):
29
28
  llm_chain: LLMChain
30
29
 
31
30
  class Config:
32
- """Configuration for this pydantic object."""
33
-
34
- extra = Extra.forbid
35
31
  arbitrary_types_allowed = True
32
+ extra = "forbid"
36
33
 
37
34
  @property
38
35
  def input_keys(self) -> List[str]:
langchain/chains/llm.py CHANGED
@@ -23,7 +23,7 @@ from langchain_core.output_parsers import BaseLLMOutputParser, StrOutputParser
23
23
  from langchain_core.outputs import ChatGeneration, Generation, LLMResult
24
24
  from langchain_core.prompt_values import PromptValue
25
25
  from langchain_core.prompts import BasePromptTemplate, PromptTemplate
26
- from langchain_core.pydantic_v1 import Extra, Field
26
+ from langchain_core.pydantic_v1 import Field
27
27
  from langchain_core.runnables import (
28
28
  Runnable,
29
29
  RunnableBinding,
@@ -96,10 +96,8 @@ class LLMChain(Chain):
96
96
  llm_kwargs: dict = Field(default_factory=dict)
97
97
 
98
98
  class Config:
99
- """Configuration for this pydantic object."""
100
-
101
- extra = Extra.forbid
102
99
  arbitrary_types_allowed = True
100
+ extra = "forbid"
103
101
 
104
102
  @property
105
103
  def input_keys(self) -> List[str]:
@@ -5,10 +5,11 @@ from __future__ import annotations
5
5
  import warnings
6
6
  from typing import Any, Dict, List, Optional
7
7
 
8
+ from langchain_core._api import deprecated
8
9
  from langchain_core.callbacks import CallbackManagerForChainRun
9
10
  from langchain_core.language_models import BaseLanguageModel
10
11
  from langchain_core.prompts import PromptTemplate
11
- from langchain_core.pydantic_v1 import Extra, root_validator
12
+ from langchain_core.pydantic_v1 import root_validator
12
13
 
13
14
  from langchain.chains.base import Chain
14
15
  from langchain.chains.llm import LLMChain
@@ -63,6 +64,15 @@ def _load_question_to_checked_assertions_chain(
63
64
  return question_to_checked_assertions_chain
64
65
 
65
66
 
67
+ @deprecated(
68
+ since="0.2.13",
69
+ message=(
70
+ "See LangGraph guides for a variety of self-reflection and corrective "
71
+ "strategies for question-answering and other tasks: "
72
+ "https://langchain-ai.github.io/langgraph/tutorials/rag/langgraph_self_rag/"
73
+ ),
74
+ removal="1.0",
75
+ )
66
76
  class LLMCheckerChain(Chain):
67
77
  """Chain for question-answering with self-verification.
68
78
 
@@ -91,10 +101,8 @@ class LLMCheckerChain(Chain):
91
101
  output_key: str = "result" #: :meta private:
92
102
 
93
103
  class Config:
94
- """Configuration for this pydantic object."""
95
-
96
- extra = Extra.forbid
97
104
  arbitrary_types_allowed = True
105
+ extra = "forbid"
98
106
 
99
107
  @root_validator(pre=True)
100
108
  def raise_deprecation(cls, values: Dict) -> Dict:
@@ -13,7 +13,7 @@ from langchain_core.callbacks import (
13
13
  )
14
14
  from langchain_core.language_models import BaseLanguageModel
15
15
  from langchain_core.prompts import BasePromptTemplate
16
- from langchain_core.pydantic_v1 import Extra, root_validator
16
+ from langchain_core.pydantic_v1 import root_validator
17
17
 
18
18
  from langchain.chains.base import Chain
19
19
  from langchain.chains.llm import LLMChain
@@ -40,10 +40,8 @@ class LLMMathChain(Chain):
40
40
  output_key: str = "answer" #: :meta private:
41
41
 
42
42
  class Config:
43
- """Configuration for this pydantic object."""
44
-
45
- extra = Extra.forbid
46
43
  arbitrary_types_allowed = True
44
+ extra = "forbid"
47
45
 
48
46
  @root_validator(pre=True)
49
47
  def raise_deprecation(cls, values: Dict) -> Dict:
@@ -6,10 +6,11 @@ import warnings
6
6
  from pathlib import Path
7
7
  from typing import Any, Dict, List, Optional
8
8
 
9
+ from langchain_core._api import deprecated
9
10
  from langchain_core.callbacks import CallbackManagerForChainRun
10
11
  from langchain_core.language_models import BaseLanguageModel
11
12
  from langchain_core.prompts.prompt import PromptTemplate
12
- from langchain_core.pydantic_v1 import Extra, root_validator
13
+ from langchain_core.pydantic_v1 import root_validator
13
14
 
14
15
  from langchain.chains.base import Chain
15
16
  from langchain.chains.llm import LLMChain
@@ -65,6 +66,15 @@ def _load_sequential_chain(
65
66
  return chain
66
67
 
67
68
 
69
+ @deprecated(
70
+ since="0.2.13",
71
+ message=(
72
+ "See LangGraph guides for a variety of self-reflection and corrective "
73
+ "strategies for question-answering and other tasks: "
74
+ "https://langchain-ai.github.io/langgraph/tutorials/rag/langgraph_self_rag/"
75
+ ),
76
+ removal="1.0",
77
+ )
68
78
  class LLMSummarizationCheckerChain(Chain):
69
79
  """Chain for question-answering with self-verification.
70
80
 
@@ -96,10 +106,8 @@ class LLMSummarizationCheckerChain(Chain):
96
106
  """Maximum number of times to check the assertions. Default to double-checking."""
97
107
 
98
108
  class Config:
99
- """Configuration for this pydantic object."""
100
-
101
- extra = Extra.forbid
102
109
  arbitrary_types_allowed = True
110
+ extra = "forbid"
103
111
 
104
112
  @root_validator(pre=True)
105
113
  def raise_deprecation(cls, values: Dict) -> Dict:
@@ -7,6 +7,7 @@ from pathlib import Path
7
7
  from typing import TYPE_CHECKING, Any, Union
8
8
 
9
9
  import yaml
10
+ from langchain_core._api import deprecated
10
11
  from langchain_core.prompts.loading import (
11
12
  _load_output_parser,
12
13
  load_prompt,
@@ -649,6 +650,14 @@ type_to_loader_dict = {
649
650
  }
650
651
 
651
652
 
653
+ @deprecated(
654
+ since="0.2.13",
655
+ message=(
656
+ "This function is deprecated and will be removed in langchain 1.0. "
657
+ "At that point chains must be imported from their respective modules."
658
+ ),
659
+ removal="1.0",
660
+ )
652
661
  def load_chain_from_config(config: dict, **kwargs: Any) -> Chain:
653
662
  """Load chain from Config Dict."""
654
663
  if "_type" not in config:
@@ -662,6 +671,14 @@ def load_chain_from_config(config: dict, **kwargs: Any) -> Chain:
662
671
  return chain_loader(config, **kwargs)
663
672
 
664
673
 
674
+ @deprecated(
675
+ since="0.2.13",
676
+ message=(
677
+ "This function is deprecated and will be removed in langchain 1.0. "
678
+ "At that point chains must be imported from their respective modules."
679
+ ),
680
+ removal="1.0",
681
+ )
665
682
  def load_chain(path: Union[str, Path], **kwargs: Any) -> Chain:
666
683
  """Unified method for loading a chain from LangChainHub or local fs."""
667
684
  if isinstance(path, str) and path.startswith("lc://"):
@@ -8,11 +8,11 @@ from __future__ import annotations
8
8
 
9
9
  from typing import Any, Dict, List, Mapping, Optional
10
10
 
11
+ from langchain_core._api import deprecated
11
12
  from langchain_core.callbacks import CallbackManagerForChainRun, Callbacks
12
13
  from langchain_core.documents import Document
13
14
  from langchain_core.language_models import BaseLanguageModel
14
15
  from langchain_core.prompts import BasePromptTemplate
15
- from langchain_core.pydantic_v1 import Extra
16
16
  from langchain_text_splitters import TextSplitter
17
17
 
18
18
  from langchain.chains import ReduceDocumentsChain
@@ -23,6 +23,16 @@ from langchain.chains.combine_documents.stuff import StuffDocumentsChain
23
23
  from langchain.chains.llm import LLMChain
24
24
 
25
25
 
26
+ @deprecated(
27
+ since="0.2.13",
28
+ removal="1.0",
29
+ message=(
30
+ "Refer here for a recommended map-reduce implementation using langgraph: "
31
+ "https://langchain-ai.github.io/langgraph/how-tos/map-reduce/. See also "
32
+ "migration guide: "
33
+ "https://python.langchain.com/v0.2/docs/versions/migrating_chains/map_reduce_chain/" # noqa: E501
34
+ ),
35
+ )
26
36
  class MapReduceChain(Chain):
27
37
  """Map-reduce chain."""
28
38
 
@@ -68,10 +78,8 @@ class MapReduceChain(Chain):
68
78
  )
69
79
 
70
80
  class Config:
71
- """Configuration for this pydantic object."""
72
-
73
- extra = Extra.forbid
74
81
  arbitrary_types_allowed = True
82
+ extra = "forbid"
75
83
 
76
84
  @property
77
85
  def input_keys(self) -> List[str]:
@@ -7,7 +7,7 @@ from typing import Any, Dict, List, Optional
7
7
 
8
8
  from langchain_core.callbacks import CallbackManagerForChainRun
9
9
  from langchain_core.language_models import BaseLanguageModel
10
- from langchain_core.pydantic_v1 import Extra, root_validator
10
+ from langchain_core.pydantic_v1 import root_validator
11
11
 
12
12
  from langchain.chains.base import Chain
13
13
  from langchain.chains.llm import LLMChain
@@ -48,10 +48,8 @@ class NatBotChain(Chain):
48
48
  output_key: str = "command" #: :meta private:
49
49
 
50
50
  class Config:
51
- """Configuration for this pydantic object."""
52
-
53
- extra = Extra.forbid
54
51
  arbitrary_types_allowed = True
52
+ extra = "forbid"
55
53
 
56
54
  @root_validator(pre=True)
57
55
  def raise_deprecation(cls, values: Dict) -> Dict:
@@ -6,6 +6,7 @@ from langchain.chains.openai_functions.base import (
6
6
  )
7
7
  from langchain.chains.openai_functions.citation_fuzzy_match import (
8
8
  create_citation_fuzzy_match_chain,
9
+ create_citation_fuzzy_match_runnable,
9
10
  )
10
11
  from langchain.chains.openai_functions.extraction import (
11
12
  create_extraction_chain,
@@ -32,6 +33,7 @@ __all__ = [
32
33
  "create_extraction_chain_pydantic",
33
34
  "create_extraction_chain",
34
35
  "create_citation_fuzzy_match_chain",
36
+ "create_citation_fuzzy_match_runnable",
35
37
  "create_qa_with_structure_chain",
36
38
  "create_qa_with_sources_chain",
37
39
  "create_structured_output_chain",
@@ -1,10 +1,12 @@
1
1
  from typing import Iterator, List
2
2
 
3
- from langchain_core.language_models import BaseLanguageModel
3
+ from langchain_core._api import deprecated
4
+ from langchain_core.language_models import BaseChatModel, BaseLanguageModel
4
5
  from langchain_core.messages import HumanMessage, SystemMessage
5
6
  from langchain_core.output_parsers.openai_functions import PydanticOutputFunctionsParser
6
7
  from langchain_core.prompts.chat import ChatPromptTemplate, HumanMessagePromptTemplate
7
8
  from langchain_core.pydantic_v1 import BaseModel, Field
9
+ from langchain_core.runnables import Runnable
8
10
 
9
11
  from langchain.chains.llm import LLMChain
10
12
  from langchain.chains.openai_functions.utils import get_llm_kwargs
@@ -61,6 +63,57 @@ class QuestionAnswer(BaseModel):
61
63
  )
62
64
 
63
65
 
66
+ def create_citation_fuzzy_match_runnable(llm: BaseChatModel) -> Runnable:
67
+ """Create a citation fuzzy match Runnable.
68
+
69
+ Example usage:
70
+
71
+ .. code-block:: python
72
+
73
+ from langchain.chains import create_citation_fuzzy_match_runnable
74
+ from langchain_openai import ChatOpenAI
75
+
76
+ llm = ChatOpenAI(model="gpt-4o-mini")
77
+
78
+ context = "Alice has blue eyes. Bob has brown eyes. Charlie has green eyes."
79
+ question = "What color are Bob's eyes?"
80
+
81
+ chain = create_citation_fuzzy_match_runnable(llm)
82
+ chain.invoke({"question": question, "context": context})
83
+
84
+ Args:
85
+ llm: Language model to use for the chain. Must implement bind_tools.
86
+
87
+ Returns:
88
+ Runnable that can be used to answer questions with citations.
89
+ """
90
+ if llm.bind_tools is BaseChatModel.bind_tools:
91
+ raise ValueError(
92
+ "Language model must implement bind_tools to use this function."
93
+ )
94
+ prompt = ChatPromptTemplate(
95
+ [
96
+ SystemMessage(
97
+ "You are a world class algorithm to answer "
98
+ "questions with correct and exact citations."
99
+ ),
100
+ HumanMessagePromptTemplate.from_template(
101
+ "Answer question using the following context."
102
+ "\n\n{context}"
103
+ "\n\nQuestion: {question}"
104
+ "\n\nTips: Make sure to cite your sources, "
105
+ "and use the exact words from the context."
106
+ ),
107
+ ]
108
+ )
109
+ return prompt | llm.with_structured_output(QuestionAnswer)
110
+
111
+
112
+ @deprecated(
113
+ since="0.2.13",
114
+ removal="1.0",
115
+ alternative="create_citation_fuzzy_match_runnable",
116
+ )
64
117
  def create_citation_fuzzy_match_chain(llm: BaseLanguageModel) -> LLMChain:
65
118
  """Create a citation fuzzy match chain.
66
119
 
@@ -6,6 +6,7 @@ from collections import defaultdict
6
6
  from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union
7
7
 
8
8
  import requests
9
+ from langchain_core._api import deprecated
9
10
  from langchain_core.callbacks import CallbackManagerForChainRun
10
11
  from langchain_core.language_models import BaseLanguageModel
11
12
  from langchain_core.output_parsers.openai_functions import JsonOutputFunctionsParser
@@ -242,6 +243,15 @@ class SimpleRequestChain(Chain):
242
243
  return {self.output_key: response}
243
244
 
244
245
 
246
+ @deprecated(
247
+ since="0.2.13",
248
+ message=(
249
+ "This function is deprecated and will be removed in langchain 1.0. "
250
+ "See API reference for replacement: "
251
+ "https://api.python.langchain.com/en/latest/chains/langchain.chains.openai_functions.openapi.get_openapi_chain.html" # noqa: E501
252
+ ),
253
+ removal="1.0",
254
+ )
245
255
  def get_openapi_chain(
246
256
  spec: Union[OpenAPISpec, str],
247
257
  llm: Optional[BaseLanguageModel] = None,
@@ -255,13 +265,90 @@ def get_openapi_chain(
255
265
  ) -> SequentialChain:
256
266
  """Create a chain for querying an API from a OpenAPI spec.
257
267
 
268
+ Note: this class is deprecated. See below for a replacement implementation.
269
+ The benefits of this implementation are:
270
+
271
+ - Uses LLM tool calling features to encourage properly-formatted API requests;
272
+ - Includes async support.
273
+
274
+ .. code-block:: python
275
+
276
+ from typing import Any
277
+
278
+ from langchain.chains.openai_functions.openapi import openapi_spec_to_openai_fn
279
+ from langchain_community.utilities.openapi import OpenAPISpec
280
+ from langchain_core.prompts import ChatPromptTemplate
281
+ from langchain_openai import ChatOpenAI
282
+
283
+ # Define API spec. Can be JSON or YAML
284
+ api_spec = \"\"\"
285
+ {
286
+ "openapi": "3.1.0",
287
+ "info": {
288
+ "title": "JSONPlaceholder API",
289
+ "version": "1.0.0"
290
+ },
291
+ "servers": [
292
+ {
293
+ "url": "https://jsonplaceholder.typicode.com"
294
+ }
295
+ ],
296
+ "paths": {
297
+ "/posts": {
298
+ "get": {
299
+ "summary": "Get posts",
300
+ "parameters": [
301
+ {
302
+ "name": "_limit",
303
+ "in": "query",
304
+ "required": false,
305
+ "schema": {
306
+ "type": "integer",
307
+ "example": 2
308
+ },
309
+ "description": "Limit the number of results"
310
+ }
311
+ ]
312
+ }
313
+ }
314
+ }
315
+ }
316
+ \"\"\"
317
+
318
+ parsed_spec = OpenAPISpec.from_text(api_spec)
319
+ openai_fns, call_api_fn = openapi_spec_to_openai_fn(parsed_spec)
320
+ tools = [
321
+ {"type": "function", "function": fn}
322
+ for fn in openai_fns
323
+ ]
324
+
325
+ prompt = ChatPromptTemplate.from_template(
326
+ "Use the provided APIs to respond to this user query:\\n\\n{query}"
327
+ )
328
+ llm = ChatOpenAI(model="gpt-4o-mini", temperature=0).bind_tools(tools)
329
+
330
+ def _execute_tool(message) -> Any:
331
+ if tool_calls := message.tool_calls:
332
+ tool_call = message.tool_calls[0]
333
+ response = call_api_fn(name=tool_call["name"], fn_args=tool_call["args"])
334
+ response.raise_for_status()
335
+ return response.json()
336
+ else:
337
+ return message.content
338
+
339
+ chain = prompt | llm | _execute_tool
340
+
341
+ .. code-block:: python
342
+
343
+ response = chain.invoke({"query": "Get me top two posts."})
344
+
258
345
  Args:
259
346
  spec: OpenAPISpec or url/file/text string corresponding to one.
260
347
  llm: language model, should be an OpenAI function-calling model, e.g.
261
348
  `ChatOpenAI(model="gpt-3.5-turbo-0613")`.
262
349
  prompt: Main prompt template to use.
263
350
  request_chain: Chain for taking the functions output and executing the request.
264
- """
351
+ """ # noqa: E501
265
352
  try:
266
353
  from langchain_community.utilities.openapi import OpenAPISpec
267
354
  except ImportError as e: