Youbiquitous / programming-llm

This is the official repository for the examples built throughout Programming Large Language Models with Azure Open AI.
https://www.microsoftpressstore.com/store/programming-large-language-models-with-azure-open-ai-9780138280376
16 stars 6 forks source link

Chapter 7, running the chat.py then got error "OutputParserException: Could not parse function call data: Expecting property name enclosed in double quotes: line 2 column 3 (char 4)" #3

Open entzyeung opened 5 days ago

entzyeung commented 5 days ago

Hello ,

I am on a WSL2 system, and in a conda env virtual environment. Python is 3.9 and is installed with the libraries in the requirement.txt.

After running the chat.py, and entering the password, I am then thrown this error. OutputParserException: Could not parse function call data: Expecting property name enclosed in double quotes: line 2 column 3 (char 4)

Traceback: File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 542, in _run_script exec(code, module.__dict__) File "/home/ubuntu2022/MyUbunDev/_pilot/3.5_turbo_redo_v2/chat.py", line 39, in <module> retriever = load_initial_data() File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/streamlit/runtime/caching/cache_utils.py", line 210, in wrapper return cached_func(*args, **kwargs) File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/streamlit/runtime/caching/cache_utils.py", line 241, in __call__ return self._get_or_create_cached_value(args, kwargs) File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/streamlit/runtime/caching/cache_utils.py", line 266, in _get_or_create_cached_value return self._handle_cache_miss(cache, value_key, func_args, func_kwargs) File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/streamlit/runtime/caching/cache_utils.py", line 322, in _handle_cache_miss computed_value = self._info.func(*func_args, **func_kwargs) File "/home/ubuntu2022/MyUbunDev/301_pilot/3.5_turbo_redo_v2/chat.py", line 36, in load_initial_data storage_service.load_pdf_files() File "/home/ubuntu2022/MyUbunDev/301_pilot/3.5_turbo_redo_v2/knowledge_service/storage.py", line 91, in load_pdf_files self._load_in_storage(pdf_documents) File "/home/ubuntu2022/MyUbunDev/301_pilot/3.5_turbo_redo_v2/knowledge_service/storage.py", line 128, in _load_in_storage parent_docs = document_transformer.transform_documents(parent_docs) File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain_community/document_transformers/openai_functions.py", line 60, in transform_documents extracted_metadata: Dict = self.tagging_chain.run(document.page_content) # type: ignore[assignment] # noqa: E501 File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain_core/_api/deprecation.py", line 148, in warning_emitting_wrapper return wrapped(*args, **kwargs) File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain/chains/base.py", line 545, in run return self(args[0], callbacks=callbacks, tags=tags, metadata=metadata)[ File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain_core/_api/deprecation.py", line 148, in warning_emitting_wrapper return wrapped(*args, **kwargs) File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain/chains/base.py", line 378, in __call__ return self.invoke( File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain/chains/base.py", line 163, in invoke raise e File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain/chains/base.py", line 153, in invoke self._call(inputs, run_manager=run_manager) File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain/chains/llm.py", line 104, in _call return self.create_outputs(response)[0] File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packa ![Screenshot 2024-10-12 190720](https://github.com/user-attachments/assets/405fcc96-03fe-465d-8185-05c467dd5989) ges/langchain/chains/llm.py", line 258, in create_outputs result = [ File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain/chains/llm.py", line 261, in <listcomp> self.output_key: self.output_parser.parse_result(generation), File "/home/ubuntu2022/miniconda/envs/_pilot/lib/python3.9/site-packages/langchain_core/output_parsers/openai_functions.py", line 102, in parse_result raise OutputParserException(

I am not sure which py file does this error happen, Would you please help? Screenshot 2024-10-14 222835

transbot commented 1 day ago

I am the translator for the Chinese edition of this book. The content in Chapter 7 for this topic is somewhat outdated, so I have made some modifications. Now, I am translating this modified content back into English (by AI) for reference.


Setting up the Project and Base UI

This section will refer to the source code accompanying the book to set up the project and a basic user interface (see the Chapter 7 folder). It assumes that a chat model has already been deployed in Azure (such as Azure OpenAI GPT-3.5-turbo or GPT 4), similar to Chapter 6. Additionally, it assumes that an embedding model has been deployed—this example uses text-embedding-ada-002. Deploy it yourself on Azure following the same steps.

After preparing the models along with their endpoints and keys, create a folder. Within it, create a .py file that will contain the application code, and create a subfolder to store the documents to be used (i.e., your own data). Then, install the following dependencies via pip:

Next, set up an .env file containing the keys, endpoint, and deployment ID of the models, and import it.

import os
import hmac
from dotenv import load_dotenv, find_dotenv
import streamlit as st

def init_env():
    _ = load_dotenv(find_dotenv())
    os.environ["LANGCHAIN_TRACING"] = "false"
    os.environ["OPENAI_API_TYPE"] = "azure"
    os.environ["OPENAI_API_VERSION"] = "2023-12-01-preview"
    os.environ["AZURE_OPENAI_ENDPOINT"] = os.getenv("AZURE_OPENAI_ENDPOINT")
    os.environ["AZURE_OPENAI_API_KEY"] = os.getenv("AZURE_OPENAI_API_KEY")

# Initialize environment
init_env()

deployment_name = os.getenv("AOAI_DEPLOYMENTID")
embeddings_deployment_name = os.getenv("AOAI_EMBEDDINGS_DEPLOYMENTID")

Now you can start creating a basic UI and workflow using Streamlit. Please use the following code:

# Set page configuration
st.set_page_config(page_title="Chapter 7", page_icon="🤖")

# Password verification function
def check_password():
    if "password_correct" in st.session_state:
        correct = st.session_state.password_correct
        return correct

    def password_entered():
        """Check if the password is correct and set session_state variable"""
        if hmac.compare_digest(st.session_state["password"], st.secrets["password"]):
            st.session_state["password_correct"] = True
            # No need to store the password
            del st.session_state["password"]
        else:
            st.session_state["password_correct"] = False

    # Display password input field
    password = st.text_input(
        "Password",
        type="password",
        on_change=password_entered,
        key="password"
    )

    # Return True if the password has been verified
    if st.session_state.get("password_correct", False):
        return True

    # If the password verification fails
    if "password_correct" in st.session_state:
        st.error("Incorrect password")
        return False

# Call the password verification function
if not check_password():
    st.stop()  # Stop execution if the password is not verified.

# Application logic after password verification
# Create a header for the AI assistant in the Streamlit app
st.header("Chapter 7 - Conversing with Your Data")

# Initialize chat message history if needed
if "messages" not in st.session_state:
    st.session_state.messages = []

# Get user input and save it to the chat history
if query := st.chat_input("Your question"):
    st.session_state.messages.append({"role": "user", "content": query})

# Display previous chat history
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.write(message["content"])

# Generate a new response if the last message is not from the assistant
if st.session_state.messages and st.session_state.messages[-1]["role"] != "assistant":
    with st.chat_message("assistant"):
        with st.spinner("Thinking..."):
            # Here we will add the required code to generate LLM output, currently generating a blank response
            response = ""
            # Display the AI-generated response
            st.write(response)
            message = {"role": "assistant", "content": response}
            # Add the response to the message history
            st.session_state.messages.append(message)

Combine the above Python code into a single .py file (e.g., chat-chinese.py), and run the command streamlit run chat-chinese.py in the terminal.[2] Input the password (password) in the automatically launched web browser page. Figure 7-2 shows the current result.


Notes:

  1. Translator's Note: The example code in this chapter is recommended to be tested in the terminal. All required modules do not need to be installed manually one by one. Switch the working directory to the Chapter 7 folder of the accompanying code and run pip install -r requirements.txt. If you need to set up a virtual environment, create one using the venv module (using the python -m venv command). Note that the provided .env.sample file should be renamed to .env after entering your API key, endpoint, and model deployment ID.

  2. Translator's Note: Do not use the original chat.py program that comes with the book, as the code does not meet the latest standards. Instead, please use the code accompanying the Chinese edition of the book (available at https://bookzhou.com).


transbot commented 1 day ago

This is the final file chat.py (named chat-chinese-final.py in the Chinese edition):

import os
import hmac
import logic.data as data
import logic.interactions as interactions
from dotenv import load_dotenv, find_dotenv
import streamlit as st

def init_env():
    _ = load_dotenv(find_dotenv())
    os.environ["LANGCHAIN_TRACING"] = "false"
    os.environ["OPENAI_API_TYPE"] = "azure"
    os.environ["OPENAI_API_VERSION"] = "2023-12-01-preview"
    os.environ["AZURE_OPENAI_ENDPOINT"] = os.getenv("AZURE_OPENAI_ENDPOINT")
    os.environ["AZURE_OPENAI_API_KEY"] = os.getenv("AZURE_OPENAI_API_KEY")

# Initialize environment
init_env()
deployment_name = os.getenv("AOAI_DEPLOYMENTID")
embeddings_deployment_name = os.getenv("AOAI_EMBEDDINGS_DEPLOYMENTID")

# Set page configuration
st.set_page_config(page_title="Chapter 7", page_icon="🤖")

# Password verification function
def check_password():
    if "password_correct" in st.session_state:
        correct = st.session_state.password_correct
        return correct

    def password_entered():
        """Check if the password is correct and set session_state variable"""
        if hmac.compare_digest(st.session_state["password"], st.secrets["password"]):
            st.session_state["password_correct"] = True
            # No need to store the password
            del st.session_state["password"]
        else:
            st.session_state["password_correct"] = False

    # Display password input field
    password = st.text_input(
        "Password",
        type="password",
        on_change=password_entered,
        key="password"
    )

    # Return True if the password has been verified
    if st.session_state.get("password_correct", False):
        return True

    # If the password verification fails
    if "password_correct" in st.session_state:
        st.error("Incorrect password")
        return False

# Call the password verification function
if not check_password():
    st.stop()  # Stop execution if the password is not verified.

# Application logic after password verification
# Create a header for the AI assistant in the Streamlit app
st.header("Chapter 7 - Conversing with Your Data")

# Initialize chat message history if needed
if "messages" not in st.session_state:
    st.session_state.messages = []

# Get user input and save it to the chat history
if query := st.chat_input("Your question"):
    st.session_state.messages.append({"role": "user", "content": query})

# Display previous chat history
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.write(message["content"])

# Generate a new response if the last message is not from the assistant
if st.session_state.messages and st.session_state.messages[-1]["role"] != "assistant":
    with st.chat_message("assistant"):
        with st.spinner("Thinking..."):
            response = interactions.run_qa_chain(query=query,
                                                 deployment=deployment_name,
                                                 retriever=retriever,
                                                 chat_history=st.session_state.messages)
    # Display the AI-generated response
    st.write(response)
    message = {"role": "assistant", "content": response}
    # Add the response to the message history
    st.session_state.messages.append(message)

def run_qa_chain(query: str, deployment: str, retriever, chat_history=[]):
    # Create an AzureChatOpenAI object
    azureopenai = AzureChatOpenAI(deployment_name=deployment, temperature=0)

    # Set up and populate memory
    memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
    for message in chat_history:
        memory.chat_memory.add_message(message=BaseMessage(type=message["role"],
                                                          content=message["content"]))

    # Create a RetrievalQA object from the chain type
    retrieval_qa = ConversationalRetrievalChain.from_llm(
        # Language model used for answering questions
        llm=azureopenai,
        # Chain type (can vary based on different use cases)
        chain_type="stuff",
        # Retriever used to fetch relevant documents
        retriever=retriever,
        # Memory reconstructed during runtime
        memory=memory,
        # For logging
        verbose=False
    )

    # Run the QA process for the provided query
    result = retrieval_qa.run(query)

    # Return the result of the QA process
    return result