libs/langchain/langchain_classic/chains/loading.py PYTHON 737 lines View on github.com → Search inside
1"""Functionality for loading chains."""23from __future__ import annotations45import json6from pathlib import Path7from typing import TYPE_CHECKING, Any89import yaml10from langchain_core._api import deprecated11from langchain_core.prompts.loading import (12    _load_output_parser,13    load_prompt,14    load_prompt_from_config,15)1617from langchain_classic.chains import ReduceDocumentsChain18from langchain_classic.chains.api.base import APIChain19from langchain_classic.chains.base import Chain20from langchain_classic.chains.combine_documents.map_reduce import (21    MapReduceDocumentsChain,22)23from langchain_classic.chains.combine_documents.map_rerank import (24    MapRerankDocumentsChain,25)26from langchain_classic.chains.combine_documents.refine import RefineDocumentsChain27from langchain_classic.chains.combine_documents.stuff import StuffDocumentsChain28from langchain_classic.chains.hyde.base import HypotheticalDocumentEmbedder29from langchain_classic.chains.llm import LLMChain30from langchain_classic.chains.llm_checker.base import LLMCheckerChain31from langchain_classic.chains.llm_math.base import LLMMathChain32from langchain_classic.chains.qa_with_sources.base import QAWithSourcesChain33from langchain_classic.chains.qa_with_sources.retrieval import (34    RetrievalQAWithSourcesChain,35)36from langchain_classic.chains.qa_with_sources.vector_db import (37    VectorDBQAWithSourcesChain,38)39from langchain_classic.chains.retrieval_qa.base import RetrievalQA, VectorDBQA4041if TYPE_CHECKING:42    from langchain_community.chains.graph_qa.cypher import GraphCypherQAChain4344    from langchain_classic.chains.llm_requests import LLMRequestsChain4546try:47    from langchain_community.llms.loading import load_llm, load_llm_from_config48except ImportError:4950    def load_llm(*_: Any, **__: Any) -> None:51        """Import error for load_llm."""52        msg = (53            "To use this load_llm functionality you must install the "54            "langchain_community package. "55            "You can install it with `pip install langchain_community`"56        )57        raise ImportError(msg)5859    def load_llm_from_config(*_: Any, **__: Any) -> None:60        """Import error for load_llm_from_config."""61        msg = (62            "To use this load_llm_from_config functionality you must install the "63            "langchain_community package. "64            "You can install it with `pip install langchain_community`"65        )66        raise ImportError(msg)676869URL_BASE = "https://raw.githubusercontent.com/hwchase17/langchain-hub/master/chains/"707172def _load_llm_chain(config: dict, **kwargs: Any) -> LLMChain:73    """Load LLM chain from config dict."""74    if "llm" in config:75        llm_config = config.pop("llm")76        llm = load_llm_from_config(llm_config, **kwargs)77    elif "llm_path" in config:78        llm = load_llm(config.pop("llm_path"), **kwargs)79    else:80        msg = "One of `llm` or `llm_path` must be present."81        raise ValueError(msg)8283    if "prompt" in config:84        prompt_config = config.pop("prompt")85        prompt = load_prompt_from_config(prompt_config)86    elif "prompt_path" in config:87        prompt = load_prompt(config.pop("prompt_path"))88    else:89        msg = "One of `prompt` or `prompt_path` must be present."90        raise ValueError(msg)91    _load_output_parser(config)9293    return LLMChain(llm=llm, prompt=prompt, **config)949596def _load_hyde_chain(config: dict, **kwargs: Any) -> HypotheticalDocumentEmbedder:97    """Load hypothetical document embedder chain from config dict."""98    if "llm_chain" in config:99        llm_chain_config = config.pop("llm_chain")100        llm_chain = load_chain_from_config(llm_chain_config, **kwargs)101    elif "llm_chain_path" in config:102        llm_chain = load_chain(config.pop("llm_chain_path"), **kwargs)103    else:104        msg = "One of `llm_chain` or `llm_chain_path` must be present."105        raise ValueError(msg)106    if "embeddings" in kwargs:107        embeddings = kwargs.pop("embeddings")108    else:109        msg = "`embeddings` must be present."110        raise ValueError(msg)111    return HypotheticalDocumentEmbedder(112        llm_chain=llm_chain,113        base_embeddings=embeddings,114        **config,115    )116117118def _load_stuff_documents_chain(config: dict, **kwargs: Any) -> StuffDocumentsChain:119    if "llm_chain" in config:120        llm_chain_config = config.pop("llm_chain")121        llm_chain = load_chain_from_config(llm_chain_config, **kwargs)122    elif "llm_chain_path" in config:123        llm_chain = load_chain(config.pop("llm_chain_path"), **kwargs)124    else:125        msg = "One of `llm_chain` or `llm_chain_path` must be present."126        raise ValueError(msg)127128    if not isinstance(llm_chain, LLMChain):129        msg = f"Expected LLMChain, got {llm_chain}"130        raise ValueError(msg)  # noqa: TRY004131132    if "document_prompt" in config:133        prompt_config = config.pop("document_prompt")134        document_prompt = load_prompt_from_config(prompt_config)135    elif "document_prompt_path" in config:136        document_prompt = load_prompt(config.pop("document_prompt_path"))137    else:138        msg = "One of `document_prompt` or `document_prompt_path` must be present."139        raise ValueError(msg)140141    return StuffDocumentsChain(142        llm_chain=llm_chain,143        document_prompt=document_prompt,144        **config,145    )146147148def _load_map_reduce_documents_chain(149    config: dict,150    **kwargs: Any,151) -> MapReduceDocumentsChain:152    if "llm_chain" in config:153        llm_chain_config = config.pop("llm_chain")154        llm_chain = load_chain_from_config(llm_chain_config, **kwargs)155    elif "llm_chain_path" in config:156        llm_chain = load_chain(config.pop("llm_chain_path"), **kwargs)157    else:158        msg = "One of `llm_chain` or `llm_chain_path` must be present."159        raise ValueError(msg)160161    if not isinstance(llm_chain, LLMChain):162        msg = f"Expected LLMChain, got {llm_chain}"163        raise ValueError(msg)  # noqa: TRY004164165    if "reduce_documents_chain" in config:166        reduce_documents_chain = load_chain_from_config(167            config.pop("reduce_documents_chain"),168            **kwargs,169        )170    elif "reduce_documents_chain_path" in config:171        reduce_documents_chain = load_chain(172            config.pop("reduce_documents_chain_path"),173            **kwargs,174        )175    else:176        reduce_documents_chain = _load_reduce_documents_chain(config, **kwargs)177178    return MapReduceDocumentsChain(179        llm_chain=llm_chain,180        reduce_documents_chain=reduce_documents_chain,181        **config,182    )183184185def _load_reduce_documents_chain(config: dict, **kwargs: Any) -> ReduceDocumentsChain:186    combine_documents_chain = None187    collapse_documents_chain = None188189    if "combine_documents_chain" in config:190        combine_document_chain_config = config.pop("combine_documents_chain")191        combine_documents_chain = load_chain_from_config(192            combine_document_chain_config,193            **kwargs,194        )195    elif "combine_document_chain" in config:196        combine_document_chain_config = config.pop("combine_document_chain")197        combine_documents_chain = load_chain_from_config(198            combine_document_chain_config,199            **kwargs,200        )201    elif "combine_documents_chain_path" in config:202        combine_documents_chain = load_chain(203            config.pop("combine_documents_chain_path"),204            **kwargs,205        )206    elif "combine_document_chain_path" in config:207        combine_documents_chain = load_chain(208            config.pop("combine_document_chain_path"),209            **kwargs,210        )211    else:212        msg = (213            "One of `combine_documents_chain` or "214            "`combine_documents_chain_path` must be present."215        )216        raise ValueError(msg)217218    if "collapse_documents_chain" in config:219        collapse_document_chain_config = config.pop("collapse_documents_chain")220        if collapse_document_chain_config is None:221            collapse_documents_chain = None222        else:223            collapse_documents_chain = load_chain_from_config(224                collapse_document_chain_config,225                **kwargs,226            )227    elif "collapse_documents_chain_path" in config:228        collapse_documents_chain = load_chain(229            config.pop("collapse_documents_chain_path"),230            **kwargs,231        )232    elif "collapse_document_chain" in config:233        collapse_document_chain_config = config.pop("collapse_document_chain")234        if collapse_document_chain_config is None:235            collapse_documents_chain = None236        else:237            collapse_documents_chain = load_chain_from_config(238                collapse_document_chain_config,239                **kwargs,240            )241    elif "collapse_document_chain_path" in config:242        collapse_documents_chain = load_chain(243            config.pop("collapse_document_chain_path"),244            **kwargs,245        )246247    return ReduceDocumentsChain(248        combine_documents_chain=combine_documents_chain,249        collapse_documents_chain=collapse_documents_chain,250        **config,251    )252253254def _load_llm_bash_chain(config: dict, **kwargs: Any) -> Any:255    """Load LLM Bash chain from config dict."""256    msg = (257        "LLMBash Chain is not available through LangChain anymore. "258        "The relevant code can be found in langchain_experimental, "259        "but it is not appropriate for production usage due to security "260        "concerns. Please refer to langchain-experimental repository for more details."261    )262    raise NotImplementedError(msg)263264265def _load_llm_checker_chain(config: dict, **kwargs: Any) -> LLMCheckerChain:266    if "llm" in config:267        llm_config = config.pop("llm")268        llm = load_llm_from_config(llm_config, **kwargs)269    elif "llm_path" in config:270        llm = load_llm(config.pop("llm_path"), **kwargs)271    else:272        msg = "One of `llm` or `llm_path` must be present."273        raise ValueError(msg)274    if "create_draft_answer_prompt" in config:275        create_draft_answer_prompt_config = config.pop("create_draft_answer_prompt")276        create_draft_answer_prompt = load_prompt_from_config(277            create_draft_answer_prompt_config,278        )279    elif "create_draft_answer_prompt_path" in config:280        create_draft_answer_prompt = load_prompt(281            config.pop("create_draft_answer_prompt_path"),282        )283    if "list_assertions_prompt" in config:284        list_assertions_prompt_config = config.pop("list_assertions_prompt")285        list_assertions_prompt = load_prompt_from_config(list_assertions_prompt_config)286    elif "list_assertions_prompt_path" in config:287        list_assertions_prompt = load_prompt(config.pop("list_assertions_prompt_path"))288    if "check_assertions_prompt" in config:289        check_assertions_prompt_config = config.pop("check_assertions_prompt")290        check_assertions_prompt = load_prompt_from_config(291            check_assertions_prompt_config,292        )293    elif "check_assertions_prompt_path" in config:294        check_assertions_prompt = load_prompt(295            config.pop("check_assertions_prompt_path"),296        )297    if "revised_answer_prompt" in config:298        revised_answer_prompt_config = config.pop("revised_answer_prompt")299        revised_answer_prompt = load_prompt_from_config(revised_answer_prompt_config)300    elif "revised_answer_prompt_path" in config:301        revised_answer_prompt = load_prompt(config.pop("revised_answer_prompt_path"))302    return LLMCheckerChain(303        llm=llm,304        create_draft_answer_prompt=create_draft_answer_prompt,305        list_assertions_prompt=list_assertions_prompt,306        check_assertions_prompt=check_assertions_prompt,307        revised_answer_prompt=revised_answer_prompt,308        **config,309    )310311312def _load_llm_math_chain(config: dict, **kwargs: Any) -> LLMMathChain:313    llm_chain = None314    if "llm_chain" in config:315        llm_chain_config = config.pop("llm_chain")316        llm_chain = load_chain_from_config(llm_chain_config, **kwargs)317    elif "llm_chain_path" in config:318        llm_chain = load_chain(config.pop("llm_chain_path"), **kwargs)319    # llm attribute is deprecated in favor of llm_chain, here to support old configs320    elif "llm" in config:321        llm_config = config.pop("llm")322        llm = load_llm_from_config(llm_config, **kwargs)323    # llm_path attribute is deprecated in favor of llm_chain_path,324    # its to support old configs325    elif "llm_path" in config:326        llm = load_llm(config.pop("llm_path"), **kwargs)327    else:328        msg = "One of `llm_chain` or `llm_chain_path` must be present."329        raise ValueError(msg)330    if "prompt" in config:331        prompt_config = config.pop("prompt")332        prompt = load_prompt_from_config(prompt_config)333    elif "prompt_path" in config:334        prompt = load_prompt(config.pop("prompt_path"))335    if llm_chain:336        return LLMMathChain(llm_chain=llm_chain, prompt=prompt, **config)337    return LLMMathChain(llm=llm, prompt=prompt, **config)338339340def _load_map_rerank_documents_chain(341    config: dict,342    **kwargs: Any,343) -> MapRerankDocumentsChain:344    if "llm_chain" in config:345        llm_chain_config = config.pop("llm_chain")346        llm_chain = load_chain_from_config(llm_chain_config, **kwargs)347    elif "llm_chain_path" in config:348        llm_chain = load_chain(config.pop("llm_chain_path"), **kwargs)349    else:350        msg = "One of `llm_chain` or `llm_chain_path` must be present."351        raise ValueError(msg)352    return MapRerankDocumentsChain(llm_chain=llm_chain, **config)353354355def _load_pal_chain(config: dict, **kwargs: Any) -> Any:356    msg = (357        "PALChain is not available through LangChain anymore. "358        "The relevant code can be found in langchain_experimental, "359        "but it is not appropriate for production usage due to security "360        "concerns. Please refer to langchain-experimental repository for more details."361    )362    raise NotImplementedError(msg)363364365def _load_refine_documents_chain(config: dict, **kwargs: Any) -> RefineDocumentsChain:366    if "initial_llm_chain" in config:367        initial_llm_chain_config = config.pop("initial_llm_chain")368        initial_llm_chain = load_chain_from_config(initial_llm_chain_config, **kwargs)369    elif "initial_llm_chain_path" in config:370        initial_llm_chain = load_chain(config.pop("initial_llm_chain_path"), **kwargs)371    else:372        msg = "One of `initial_llm_chain` or `initial_llm_chain_path` must be present."373        raise ValueError(msg)374    if "refine_llm_chain" in config:375        refine_llm_chain_config = config.pop("refine_llm_chain")376        refine_llm_chain = load_chain_from_config(refine_llm_chain_config, **kwargs)377    elif "refine_llm_chain_path" in config:378        refine_llm_chain = load_chain(config.pop("refine_llm_chain_path"), **kwargs)379    else:380        msg = "One of `refine_llm_chain` or `refine_llm_chain_path` must be present."381        raise ValueError(msg)382    if "document_prompt" in config:383        prompt_config = config.pop("document_prompt")384        document_prompt = load_prompt_from_config(prompt_config)385    elif "document_prompt_path" in config:386        document_prompt = load_prompt(config.pop("document_prompt_path"))387    return RefineDocumentsChain(388        initial_llm_chain=initial_llm_chain,389        refine_llm_chain=refine_llm_chain,390        document_prompt=document_prompt,391        **config,392    )393394395def _load_qa_with_sources_chain(config: dict, **kwargs: Any) -> QAWithSourcesChain:396    if "combine_documents_chain" in config:397        combine_documents_chain_config = config.pop("combine_documents_chain")398        combine_documents_chain = load_chain_from_config(399            combine_documents_chain_config,400            **kwargs,401        )402    elif "combine_documents_chain_path" in config:403        combine_documents_chain = load_chain(404            config.pop("combine_documents_chain_path"),405            **kwargs,406        )407    else:408        msg = (409            "One of `combine_documents_chain` or "410            "`combine_documents_chain_path` must be present."411        )412        raise ValueError(msg)413    return QAWithSourcesChain(combine_documents_chain=combine_documents_chain, **config)414415416def _load_sql_database_chain(config: dict, **kwargs: Any) -> Any:417    """Load SQL Database chain from config dict."""418    msg = (419        "SQLDatabaseChain is not available through LangChain anymore. "420        "The relevant code can be found in langchain_experimental, "421        "but it is not appropriate for production usage due to security "422        "concerns. Please refer to langchain-experimental repository for more details, "423        "or refer to this tutorial for best practices: "424        "https://python.langchain.com/docs/tutorials/sql_qa/"425    )426    raise NotImplementedError(msg)427428429def _load_vector_db_qa_with_sources_chain(430    config: dict,431    **kwargs: Any,432) -> VectorDBQAWithSourcesChain:433    if "vectorstore" in kwargs:434        vectorstore = kwargs.pop("vectorstore")435    else:436        msg = "`vectorstore` must be present."437        raise ValueError(msg)438    if "combine_documents_chain" in config:439        combine_documents_chain_config = config.pop("combine_documents_chain")440        combine_documents_chain = load_chain_from_config(441            combine_documents_chain_config,442            **kwargs,443        )444    elif "combine_documents_chain_path" in config:445        combine_documents_chain = load_chain(446            config.pop("combine_documents_chain_path"),447            **kwargs,448        )449    else:450        msg = (451            "One of `combine_documents_chain` or "452            "`combine_documents_chain_path` must be present."453        )454        raise ValueError(msg)455    return VectorDBQAWithSourcesChain(456        combine_documents_chain=combine_documents_chain,457        vectorstore=vectorstore,458        **config,459    )460461462def _load_retrieval_qa(config: dict, **kwargs: Any) -> RetrievalQA:463    if "retriever" in kwargs:464        retriever = kwargs.pop("retriever")465    else:466        msg = "`retriever` must be present."467        raise ValueError(msg)468    if "combine_documents_chain" in config:469        combine_documents_chain_config = config.pop("combine_documents_chain")470        combine_documents_chain = load_chain_from_config(471            combine_documents_chain_config,472            **kwargs,473        )474    elif "combine_documents_chain_path" in config:475        combine_documents_chain = load_chain(476            config.pop("combine_documents_chain_path"),477            **kwargs,478        )479    else:480        msg = (481            "One of `combine_documents_chain` or "482            "`combine_documents_chain_path` must be present."483        )484        raise ValueError(msg)485    return RetrievalQA(486        combine_documents_chain=combine_documents_chain,487        retriever=retriever,488        **config,489    )490491492def _load_retrieval_qa_with_sources_chain(493    config: dict,494    **kwargs: Any,495) -> RetrievalQAWithSourcesChain:496    if "retriever" in kwargs:497        retriever = kwargs.pop("retriever")498    else:499        msg = "`retriever` must be present."500        raise ValueError(msg)501    if "combine_documents_chain" in config:502        combine_documents_chain_config = config.pop("combine_documents_chain")503        combine_documents_chain = load_chain_from_config(504            combine_documents_chain_config,505            **kwargs,506        )507    elif "combine_documents_chain_path" in config:508        combine_documents_chain = load_chain(509            config.pop("combine_documents_chain_path"),510            **kwargs,511        )512    else:513        msg = (514            "One of `combine_documents_chain` or "515            "`combine_documents_chain_path` must be present."516        )517        raise ValueError(msg)518    return RetrievalQAWithSourcesChain(519        combine_documents_chain=combine_documents_chain,520        retriever=retriever,521        **config,522    )523524525def _load_vector_db_qa(config: dict, **kwargs: Any) -> VectorDBQA:526    if "vectorstore" in kwargs:527        vectorstore = kwargs.pop("vectorstore")528    else:529        msg = "`vectorstore` must be present."530        raise ValueError(msg)531    if "combine_documents_chain" in config:532        combine_documents_chain_config = config.pop("combine_documents_chain")533        combine_documents_chain = load_chain_from_config(534            combine_documents_chain_config,535            **kwargs,536        )537    elif "combine_documents_chain_path" in config:538        combine_documents_chain = load_chain(539            config.pop("combine_documents_chain_path"),540            **kwargs,541        )542    else:543        msg = (544            "One of `combine_documents_chain` or "545            "`combine_documents_chain_path` must be present."546        )547        raise ValueError(msg)548    return VectorDBQA(549        combine_documents_chain=combine_documents_chain,550        vectorstore=vectorstore,551        **config,552    )553554555def _load_graph_cypher_chain(config: dict, **kwargs: Any) -> GraphCypherQAChain:556    if "graph" in kwargs:557        graph = kwargs.pop("graph")558    else:559        msg = "`graph` must be present."560        raise ValueError(msg)561    if "cypher_generation_chain" in config:562        cypher_generation_chain_config = config.pop("cypher_generation_chain")563        cypher_generation_chain = load_chain_from_config(564            cypher_generation_chain_config,565            **kwargs,566        )567    else:568        msg = "`cypher_generation_chain` must be present."569        raise ValueError(msg)570    if "qa_chain" in config:571        qa_chain_config = config.pop("qa_chain")572        qa_chain = load_chain_from_config(qa_chain_config, **kwargs)573    else:574        msg = "`qa_chain` must be present."575        raise ValueError(msg)576577    try:578        from langchain_community.chains.graph_qa.cypher import GraphCypherQAChain579    except ImportError as e:580        msg = (581            "To use this GraphCypherQAChain functionality you must install the "582            "langchain_community package. "583            "You can install it with `pip install langchain_community`"584        )585        raise ImportError(msg) from e586    return GraphCypherQAChain(587        graph=graph,588        cypher_generation_chain=cypher_generation_chain,589        qa_chain=qa_chain,590        **config,591    )592593594def _load_api_chain(config: dict, **kwargs: Any) -> APIChain:595    if "api_request_chain" in config:596        api_request_chain_config = config.pop("api_request_chain")597        api_request_chain = load_chain_from_config(api_request_chain_config, **kwargs)598    elif "api_request_chain_path" in config:599        api_request_chain = load_chain(config.pop("api_request_chain_path"))600    else:601        msg = "One of `api_request_chain` or `api_request_chain_path` must be present."602        raise ValueError(msg)603    if "api_answer_chain" in config:604        api_answer_chain_config = config.pop("api_answer_chain")605        api_answer_chain = load_chain_from_config(api_answer_chain_config, **kwargs)606    elif "api_answer_chain_path" in config:607        api_answer_chain = load_chain(config.pop("api_answer_chain_path"), **kwargs)608    else:609        msg = "One of `api_answer_chain` or `api_answer_chain_path` must be present."610        raise ValueError(msg)611    if "requests_wrapper" in kwargs:612        requests_wrapper = kwargs.pop("requests_wrapper")613    else:614        msg = "`requests_wrapper` must be present."615        raise ValueError(msg)616    return APIChain(617        api_request_chain=api_request_chain,618        api_answer_chain=api_answer_chain,619        requests_wrapper=requests_wrapper,620        **config,621    )622623624def _load_llm_requests_chain(config: dict, **kwargs: Any) -> LLMRequestsChain:625    try:626        from langchain_classic.chains.llm_requests import LLMRequestsChain627    except ImportError as e:628        msg = (629            "To use this LLMRequestsChain functionality you must install the "630            "langchain package. "631            "You can install it with `pip install langchain`"632        )633        raise ImportError(msg) from e634635    if "llm_chain" in config:636        llm_chain_config = config.pop("llm_chain")637        llm_chain = load_chain_from_config(llm_chain_config, **kwargs)638    elif "llm_chain_path" in config:639        llm_chain = load_chain(config.pop("llm_chain_path"), **kwargs)640    else:641        msg = "One of `llm_chain` or `llm_chain_path` must be present."642        raise ValueError(msg)643    if "requests_wrapper" in kwargs:644        requests_wrapper = kwargs.pop("requests_wrapper")645        return LLMRequestsChain(646            llm_chain=llm_chain,647            requests_wrapper=requests_wrapper,648            **config,649        )650    return LLMRequestsChain(llm_chain=llm_chain, **config)651652653type_to_loader_dict = {654    "api_chain": _load_api_chain,655    "hyde_chain": _load_hyde_chain,656    "llm_chain": _load_llm_chain,657    "llm_bash_chain": _load_llm_bash_chain,658    "llm_checker_chain": _load_llm_checker_chain,659    "llm_math_chain": _load_llm_math_chain,660    "llm_requests_chain": _load_llm_requests_chain,661    "pal_chain": _load_pal_chain,662    "qa_with_sources_chain": _load_qa_with_sources_chain,663    "stuff_documents_chain": _load_stuff_documents_chain,664    "map_reduce_documents_chain": _load_map_reduce_documents_chain,665    "reduce_documents_chain": _load_reduce_documents_chain,666    "map_rerank_documents_chain": _load_map_rerank_documents_chain,667    "refine_documents_chain": _load_refine_documents_chain,668    "sql_database_chain": _load_sql_database_chain,669    "vector_db_qa_with_sources_chain": _load_vector_db_qa_with_sources_chain,670    "vector_db_qa": _load_vector_db_qa,671    "retrieval_qa": _load_retrieval_qa,672    "retrieval_qa_with_sources_chain": _load_retrieval_qa_with_sources_chain,673    "graph_cypher_chain": _load_graph_cypher_chain,674}675676677@deprecated(678    since="0.2.13",679    removal="2.0.0",680    addendum="Chains must be imported from their respective modules.",681)682def load_chain_from_config(config: dict, **kwargs: Any) -> Chain:683    """Load chain from Config Dict."""684    if "_type" not in config:685        msg = "Must specify a chain Type in config"686        raise ValueError(msg)687    config_type = config.pop("_type")688689    if config_type not in type_to_loader_dict:690        msg = f"Loading {config_type} chain not supported"691        raise ValueError(msg)692693    chain_loader = type_to_loader_dict[config_type]694    return chain_loader(config, **kwargs)695696697@deprecated(698    since="0.2.13",699    removal="2.0.0",700    addendum="Chains must be imported from their respective modules.",701)702def load_chain(path: str | Path, **kwargs: Any) -> Chain:703    """Unified method for loading a chain from LangChainHub or local fs."""704    if isinstance(path, str) and path.startswith("lc://"):705        msg = (706            "Loading from the deprecated github-based Hub is no longer supported. "707            "Please use the new LangChain Hub at https://smith.langchain.com/hub "708            "instead."709        )710        raise RuntimeError(msg)711    return _load_chain_from_file(path, **kwargs)712713714def _load_chain_from_file(file: str | Path, **kwargs: Any) -> Chain:715    """Load chain from file."""716    # Convert file to Path object.717    file_path = Path(file) if isinstance(file, str) else file718    # Load from either json or yaml.719    if file_path.suffix == ".json":720        with file_path.open() as f:721            config = json.load(f)722    elif file_path.suffix.endswith((".yaml", ".yml")):723        with file_path.open() as f:724            config = yaml.safe_load(f)725    else:726        msg = "File type must be json or yaml"727        raise ValueError(msg)728729    # Override default 'verbose' and 'memory' for the chain730    if "verbose" in kwargs:731        config["verbose"] = kwargs.pop("verbose")732    if "memory" in kwargs:733        config["memory"] = kwargs.pop("memory")734735    # Load the chain from the config now.736    return load_chain_from_config(config, **kwargs)

Code quality findings 4

Overuse may indicate design issues; consider polymorphism
isinstance-overuse
if not isinstance(llm_chain, LLMChain):
Overuse may indicate design issues; consider polymorphism
isinstance-overuse
if not isinstance(llm_chain, LLMChain):
Overuse may indicate design issues; consider polymorphism
isinstance-overuse
if isinstance(path, str) and path.startswith("lc://"):
Overuse may indicate design issues; consider polymorphism
isinstance-overuse
file_path = Path(file) if isinstance(file, str) else file

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.