langchain-ai / langchain

🦜🔗 Build context-aware reasoning applications
https://python.langchain.com
MIT License
92.9k stars 14.89k forks source link

I am getting pydantic Validation error when expecting tools in a response #26777

Open tkmptech opened 6 days ago

tkmptech commented 6 days ago

Checked other resources

Example Code

The Following code:

from datetime import datetime
from typing import List

from langchain_core.messages import (
    SystemMessage,
    HumanMessage,
    ToolMessage,
    trim_messages,
)
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

# from openai import BaseModel
from pydantic.v1 import BaseModel, Field

## My messages in this format are accepted
 def build_message_list(self) -> List:
        # Convert internal history to a list of SystemMessage, HumanMessage, AIMessage, ToolMessage
        messages = [
            SystemMessage(
                content=""" \n Do Not make Vague assumptions use 
        appropriate tools provided whenever required to extract new or next Question."""
            )
        ]
        for entry in self.history:
            if entry["role"] == "human":
                messages.append(HumanMessage(content=entry["content"]))
            elif entry["role"] == "assistant":
                messages.append(AIMessage(content=entry["content"]))
            elif entry["role"] == "tool":
                messages.append(ToolMessage(content=entry["content"]))
        return messages
# this is the function where i should expect a AIMessage.
  def invoke_tool_or_model(self, messages) -> dict:
      """Handles whether to invoke a tool or continue with the LLM."""
      last_message = messages[-1]
      if hasattr(last_message, "tool_calls") and last_message.tool_calls:
          return self.call_tools(last_message.tool_calls)
      else:
          prompt = self.format_trimmed_history(messages)

          response = self.llm.invoke(prompt)
          return response

Error Message and Stack Trace (if applicable)

the json response is giving the error inside the "tool_calls" where the accepted format is not decoded.

D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\pydantic\main.py:390: UserWarning: Pydantic serializer warnings:
  Expected `str` but got `dict` with value `{'category': 'math'}` - serialized value may not be as expected
  return self.__pydantic_serializer__.to_python(
2024-09-23 18:39:55.381 Uncaught app exception
Traceback (most recent call last):
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\streamlit\runtime\scriptrunner\exec_code.py", line 88, in exec_func_with_error_handling
    result = func()
             ^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 590, in code_to_exec
    exec(code, module.__dict__)
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\ai_interviewer_streamlit\new_interviewer.py", line 256, in <module>
    main()
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\ai_interviewer_streamlit\new_interviewer.py", line 249, in main
    handle_chat(interviewer)
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\ai_interviewer_streamlit\new_interviewer.py", line 200, in handle_chat
    response = interviewer.text_to_text(user_input)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\ai_interviewer_streamlit\new_interviewer.py", line 82, in text_to_text
    response = self.invoke_tool_or_model(trimmed_messages)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\ai_interviewer_streamlit\new_interviewer.py", line 114, in invoke_tool_or_model
    response = self.llm.invoke(prompt)
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\runnables\base.py", line 5343, in invoke
    return self.bound.invoke(
           ^^^^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\language_models\chat_models.py", line 284, in invoke
    self.generate_prompt(
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\language_models\chat_models.py", line 784, in generate_prompt
    return self.generate(prompt_messages, stop=stop, callbacks=callbacks, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\language_models\chat_models.py", line 641, in generate
    raise e
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\language_models\chat_models.py", line 631, in generate
    self._generate_with_cache(
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\language_models\chat_models.py", line 853, in _generate_with_cache
    result = self._generate(
             ^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_openai\chat_models\base.py", line 671, in _generate
    return self._create_chat_result(response, generation_info)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_openai\chat_models\base.py", line 708, in _create_chat_result
    message = _convert_dict_to_message(res["message"])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_openai\chat_models\base.py", line 127, in _convert_dict_to_message
    return AIMessage(
           ^^^^^^^^^^
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\messages\ai.py", line 94, in __init__
    super().__init__(content=content, **kwargs)
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\messages\base.py", line 76, in __init__
    super().__init__(content=content, **kwargs)
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\langchain_core\load\serializable.py", line 110, in __init__
    super().__init__(*args, **kwargs)
  File "D:\Work\Company_Product_Brainstorming\Sample_projects\GPTInterviewer\Final\envinter\Lib\site-packages\pydantic\main.py", line 212, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 1 validation error for AIMessage
invalid_tool_calls.0.args
  Input should be a valid string [type=string_type, input_value={'category': 'math'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.9/v/string_type

Description

System Info

System Information

OS: Windows OS Version: 10.0.19045 Python Version: 3.12.5 | packaged by conda-forge | (main, Aug 8 2024, 18:24:51) [MSC v.1940 64 bit (AMD64)]

Package Information

langchain_core: 0.3.5 langchain: 0.2.16 langchain_community: 0.2.16 langsmith: 0.1.125 langchain_openai: 0.2.0 langchain_text_splitters: 0.2.2

Optional packages not installed

langgraph langserve

Other Dependencies

aiohttp: 3.10.5 async-timeout: Installed. No version info available. dataclasses-json: 0.6.7 httpx: 0.27.2 jsonpatch: 1.33 numpy: 1.26.4 openai: 1.46.0 orjson: 3.10.7 packaging: 23.2 pydantic: 2.8.2 PyYAML: 6.0.2 requests: 2.32.3 SQLAlchemy: 2.0.32 tenacity: 8.5.0 tiktoken: 0.7.0 typing-extensions: 4.12.2

keenborder786 commented 6 days ago

@tkmptech their something wrong with your tool schema. Cannot help you unless you provide the tool schema that you are using. This validation error usually occurrs when AI calls for schema which is different then what you have specified.

tkmptech commented 6 days ago
@tool
def GetNewQuestion(category) -> str:
    """Fetch a new interview question based on the provided category."""
    # Check if category is a dict and extract the value, otherwise use it directly
    if isinstance(category, dict):
        category = category.get(
            "category", "general"
        )  # default to 'general' if key is missing

    return f"What is your experience with {category}?"

def main():
    # Initialize the UI and get persona
    persona, N_folder = init_ui()

    # Initialize LLM
    llm = ChatOpenAI(
        openai_api_base=st.text_input("Enter the model URL:"),
        openai_api_key="your-api-key-here",
        model_name="gpt-3.5-turbo",
        max_retries=1,
        openai_organization="your-organization-id-here",
    )
    tools = [GetNewQuestion]  # Define the available tools
    llm = llm.bind_tools(tools, tool_choice="GetNewQuestion")

    ChatBot = CHATBOT(persona, llm, tools)

    # Handle chat interaction
    handle_chat(ChatBot)

    # Option to save the conversation history
    save_chat_history()

This is my tool schema and main function to handle all the chat but at the end it calls "invoke_tool_or_model"

m7mdhka commented 5 days ago

I've error like him

Traceback (most recent call last):
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.QueryGenerator\app.py", line 42, in <module>
    query_generator.generate_query(user_request)
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.QueryGenerator\core\sql_agent.py", line 107, in generate_query
    response = self.agent_executor.invoke(
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\langchain\chains\base.py", line 170, in invoke
    raise e
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\langchain\chains\base.py", line 165, in invoke
    final_outputs: Dict[str, Any] = self.prep_outputs(
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\langchain\chains\base.py", line 466, in prep_outputs
    self.memory.save_context(inputs, outputs)
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\langchain\memory\chat_memory.py", line 57, in save_context
    [HumanMessage(content=input_str), AIMessage(content=output_str)]
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\langchain_core\messages\human.py", line 56, in __init__
    super().__init__(content=content, **kwargs)
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\langchain_core\messages\base.py", line 76, in __init__
    super().__init__(content=content, **kwargs)
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\langchain_core\load\serializable.py", line 110, in __init__
    super().__init__(*args, **kwargs)
  File "C:\Users\m.rahamneh\Documents\MiTool\Minerets.SQLGenerator\.sqlgenenv\lib\site-packages\pydantic\main.py", line 212, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
pydantic_core._pydantic_core.ValidationError: 5 validation errors for HumanMessage
content.str
  Input should be a valid string [type=string_type, input_value=[SystemMessage(content='\..., response_metadata={})], input_type=list]
    For further information visit https://errors.pydantic.dev/2.9/v/string_type
content.list[union[str,dict[any,any]]].0.str
  Input should be a valid string [type=string_type, input_value=SystemMessage(content='\n...}, response_metadata={}), input_type=SystemMessage]
    For further information visit https://errors.pydantic.dev/2.9/v/string_type
content.list[union[str,dict[any,any]]].0.dict[any,any]
  Input should be a valid dictionary [type=dict_type, input_value=SystemMessage(content='\n...}, response_metadata={}), input_type=SystemMessage]
    For further information visit https://errors.pydantic.dev/2.9/v/dict_type
content.list[union[str,dict[any,any]]].1.str
  Input should be a valid string [type=string_type, input_value=HumanMessage(content='wha...}, response_metadata={}), input_type=HumanMessage]
    For further information visit https://errors.pydantic.dev/2.9/v/string_type
content.list[union[str,dict[any,any]]].1.dict[any,any]
  Input should be a valid dictionary [type=dict_type, input_value=HumanMessage(content='wha...}, response_metadata={}), input_type=HumanMessage]
    For further information visit https://errors.pydantic.dev/2.9/v/dict_type
       def generate_query(self, input):
        prompt = ChatPromptTemplate.from_messages(
            [
                SystemMessage(
                    content=system_message
                ),
                HumanMessage(content=input),
            ]
        )

        formatted_messages = prompt.format_messages(input=input)
        response = self.agent_executor.invoke(
            {
                "input": formatted_messages
            }
        )

        return response
kteppris commented 3 days ago

I encounter the same issue. The llama 3.1 Model returns the correct Format, just that it comes back a dict instead of a string in json format and than the PyDantic parsing fails. I tried already with prompting to changes this but no success so far.

I use HF TGI as Inference API.