admin管理员组

文章数量:1302292

The question I cannot figure out is this: we have a langchain method with_structured_output() which create a runnable llm to have a structured output as a pydantic class. How I can combine this inside a Chain I have to use for example to have a retrieval, when this chains seem to need runnable which give string type as output?

Here my code:

`from dotenv import load_dotenv
load_dotenv()
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain_openai.chat_models import AzureChatOpenAI
from langchain_openai import AzureOpenAIEmbeddings
from langchain.chains import create_retrieval_chain
from langchain.chainsbine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from typing import Optional

from pydantic import BaseModel, Field

# Load from local storage
persisted_vectorstore = FAISS.load_local("faiss_index", embedding_function, allow_dangerous_deserialization=True)

# Pydantic
class TechnicalDescription(BaseModel):
    """Technical description requested from the user."""

    architecture: str = Field(description="The architecture of the object requested")
    functionality: str = Field(description="The functionality of the object requested")
    complexity_rating: Optional[int] = Field(
        default=None, description="How complex the object requested is, from 1 to 10"
    )

system_prompt = (
    "Usa il contesto fornito per rispondere alla domanda. "
    "Se non sai la risposta, rispondi con 'non lo so' "
    "Sii conciso nella risposta. "
    "Context: {context}"
)
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system_prompt),
        ("human", "{input}"),
    ]
)

llm = AzureChatOpenAI(azure_endpoint=os.getenv("ENDPOINT_GPT"),
                    api_version=os.getenv("OPENAI_API_VERSION_GPT"),
                    api_key=os.getenv("OPENAI_API_KEY_GPT"),
                    model=os.getenv("OPENAI_API_MODEL_DEPLOYMENT_NAME_GPT"),
                    temperature=0,
                    max_tokens=4096)

structured_llm = llm.with_structured_output(TechnicalDescription)
retriever=persisted_vectorstore.as_retriever()
question_answer_chain = create_stuff_documents_chain(structured_llm, prompt)
chain = create_retrieval_chain(retriever, question_answer_chain)
chain.invoke({"input": "What is an LLM?"})`

and here the error I receive:

 ---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Cell In[25], line 4
      2 question_answer_chain = create_stuff_documents_chain(structured_llm, prompt)
      3 chain = create_retrieval_chain(retriever, question_answer_chain)
----> 4 chain.invoke({"input": "What is an LLM?"})

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:5352, in RunnableBindingBase.invoke(self, input, config, **kwargs)
   5346 def invoke(
   5347     self,
   5348     input: Input,
   5349     config: Optional[RunnableConfig] = None,
   5350     **kwargs: Optional[Any],
   5351 ) -> Output:
-> 5352     return self.bound.invoke(
   5353         input,
   5354         self._merge_configs(config),
   5355         **{**self.kwargs, **kwargs},
   5356     )

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:3016, in RunnableSequence.invoke(self, input, config, **kwargs)
   3014             input = context.run(step.invoke, input, config, **kwargs)
   3015         else:
-> 3016             input = context.run(step.invoke, input, config)
   3017 # finish the root run
   3018 except BaseException as e:

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\passthrough.py:494, in RunnableAssign.invoke(self, input, config, **kwargs)
    488 def invoke(
    489     self,
    490     input: dict[str, Any],
    491     config: Optional[RunnableConfig] = None,
    492     **kwargs: Any,
    493 ) -> dict[str, Any]:
--> 494     return self._call_with_config(self._invoke, input, config, **kwargs)

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:1914, in Runnable._call_with_config(self, func, input, config, run_type, serialized, **kwargs)
   1910     context = copy_context()
   1911     context.run(_set_config_context, child_config)
   1912     output = cast(
   1913         Output,
-> 1914         context.run(
   1915             call_func_with_variable_args,  # type: ignore[arg-type]
   1916             func,  # type: ignore[arg-type]
   1917             input,  # type: ignore[arg-type]
   1918             config,
   1919             run_manager,
   1920             **kwargs,
   1921         ),
   1922     )
   1923 except BaseException as e:
   1924     run_manager.on_chain_error(e)

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\config.py:396, in call_func_with_variable_args(func, input, config, run_manager, **kwargs)
    394 if run_manager is not None and accepts_run_manager(func):
    395     kwargs["run_manager"] = run_manager
--> 396 return func(input, **kwargs)

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\passthrough.py:481, in RunnableAssign._invoke(self, input, run_manager, config, **kwargs)
    476     msg = "The input to RunnablePassthrough.assign() must be a dict."
    477     raise ValueError(msg)  # noqa: TRY004
    479 return {
    480     **input,
--> 481     **self.mapper.invoke(
    482         input,
    483         patch_config(config, callbacks=run_manager.get_child()),
    484         **kwargs,
    485     ),
    486 }

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:3721, in RunnableParallel.invoke(self, input, config, **kwargs)
   3716     with get_executor_for_config(config) as executor:
   3717         futures = [
   3718             executor.submit(_invoke_step, step, input, config, key)
   3719             for key, step in steps.items()
   3720         ]
-> 3721         output = {key: future.result() for key, future in zip(steps, futures)}
   3722 # finish the root run
   3723 except BaseException as e:

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:3721, in <dictcomp>(.0)
   3716     with get_executor_for_config(config) as executor:
   3717         futures = [
   3718             executor.submit(_invoke_step, step, input, config, key)
   3719             for key, step in steps.items()
   3720         ]
-> 3721         output = {key: future.result() for key, future in zip(steps, futures)}
   3722 # finish the root run
   3723 except BaseException as e:

File ~\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\_base.py:456, in Future.result(self, timeout)
    454     raise CancelledError()
    455 elif self._state == FINISHED:
--> 456     return self.__get_result()
    457 else:
    458     raise TimeoutError()

File ~\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\_base.py:401, in Future.__get_result(self)
    399 if self._exception:
    400     try:
--> 401         raise self._exception
    402     finally:
    403         # Break a reference cycle with the exception in self._exception
    404         self = None

File ~\AppData\Local\Programs\Python\Python311\Lib\concurrent\futures\thread.py:58, in _WorkItem.run(self)
     55     return
     57 try:
---> 58     result = self.fn(*self.args, **self.kwargs)
     59 except BaseException as exc:
     60     self.future.set_exception(exc)

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:3705, in RunnableParallel.invoke.<locals>._invoke_step(step, input, config, key)
   3703 context = copy_context()
   3704 context.run(_set_config_context, child_config)
-> 3705 return context.run(
   3706     step.invoke,
   3707     input,
   3708     child_config,
   3709 )

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:5352, in RunnableBindingBase.invoke(self, input, config, **kwargs)
   5346 def invoke(
   5347     self,
   5348     input: Input,
   5349     config: Optional[RunnableConfig] = None,
   5350     **kwargs: Optional[Any],
   5351 ) -> Output:
-> 5352     return self.bound.invoke(
   5353         input,
   5354         self._merge_configs(config),
   5355         **{**self.kwargs, **kwargs},
   5356     )

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:3016, in RunnableSequence.invoke(self, input, config, **kwargs)
   3014             input = context.run(step.invoke, input, config, **kwargs)
   3015         else:
-> 3016             input = context.run(step.invoke, input, config)
   3017 # finish the root run
   3018 except BaseException as e:

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\output_parsers\base.py:202, in BaseOutputParser.invoke(self, input, config, **kwargs)
    193     return self._call_with_config(
    194         lambda inner_input: self.parse_result(
    195             [ChatGeneration(message=inner_input)]
   (...)
    199         run_type="parser",
    200     )
    201 else:
--> 202     return self._call_with_config(
    203         lambda inner_input: self.parse_result([Generation(text=inner_input)]),
    204         input,
    205         config,
    206         run_type="parser",
    207     )

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\base.py:1914, in Runnable._call_with_config(self, func, input, config, run_type, serialized, **kwargs)
   1910     context = copy_context()
   1911     context.run(_set_config_context, child_config)
   1912     output = cast(
   1913         Output,
-> 1914         context.run(
   1915             call_func_with_variable_args,  # type: ignore[arg-type]
   1916             func,  # type: ignore[arg-type]
   1917             input,  # type: ignore[arg-type]
   1918             config,
   1919             run_manager,
   1920             **kwargs,
   1921         ),
   1922     )
   1923 except BaseException as e:
   1924     run_manager.on_chain_error(e)

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\runnables\config.py:396, in call_func_with_variable_args(func, input, config, run_manager, **kwargs)
    394 if run_manager is not None and accepts_run_manager(func):
    395     kwargs["run_manager"] = run_manager
--> 396 return func(input, **kwargs)

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\output_parsers\base.py:203, in BaseOutputParser.invoke.<locals>.<lambda>(inner_input)
    193     return self._call_with_config(
    194         lambda inner_input: self.parse_result(
    195             [ChatGeneration(message=inner_input)]
   (...)
    199         run_type="parser",
    200     )
    201 else:
    202     return self._call_with_config(
--> 203         lambda inner_input: self.parse_result([Generation(text=inner_input)]),
    204         input,
    205         config,
    206         run_type="parser",
    207     )

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\langchain_core\load\serializable.py:125, in Serializable.__init__(self, *args, **kwargs)
    123 def __init__(self, *args: Any, **kwargs: Any) -> None:
    124     """"""
--> 125     super().__init__(*args, **kwargs)

File c:\Users\gabriele.volpi\OneDrive - Accenture\Documents\GenerativeAI\InternalTraining\.venv\Lib\site-packages\pydantic\main.py:214, in BaseModel.__init__(self, **data)
    212 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
    213 __tracebackhide__ = True
--> 214 validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
    215 if self is not validated_self:
    216     warnings.warn(
    217         'A custom validator is returning a value other than `self`.\n'
    218         "Returning anything other than `self` from a top level model validator isn't supported when validating via `__init__`.\n"
    219         'See the `model_validator` docs (/latest/concepts/validators/#model-validators) for more details.',
    220         stacklevel=2,
    221     )

ValidationError: 1 validation error for Generation
text
  Input should be a valid string [type=string_type, input_value=TechnicalDescription(arch....', complexity_rating=8), input_type=TechnicalDescription]
    For further information visit /2.10/v/string_type

I expected to receive a chain which I could invoke to have a structured output as defined

本文标签: pythonLangchain chains with structured outputsStack Overflow