Functions might not be supported through Azure OpenAI
Labels: name: bug

### System Info

Windows 10

Name: langchain
Version: 0.0.208
Summary: Building applications with LLMs through composability


### Who can help?

_No response_

### Information

- [ ] The official example notebooks/scripts
- [X] My own modified scripts

### Related Components

- [X] LLMs/Chat Models
- [ ] Embedding Models
- [ ] Prompts / Prompt Templates / Prompt Selectors
- [ ] Output Parsers
- [ ] Document Loaders
- [ ] Vector Stores / Retrievers
- [ ] Memory
- [ ] Agents / Agent Executors
- [X] Tools / Toolkits
- [ ] Chains
- [ ] Callbacks/Tracing
- [ ] Async

### Reproduction

```python
from pydantic import BaseModel, Field

from langchain.chat_models import ChatOpenAI, AzureChatOpenAI
from langchain.agents import Tool
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.document_loaders import PyPDFLoader
from langchain.chains import RetrievalQA


# Here a proper Azure OpenAI service needs to be defined

OPENAI_API_KEY=" "
OPENAI_DEPLOYMENT_ENDPOINT="https://gptkbopenai.openai.azure.com/"

OPENAI_DEPLOYMENT_NAME = "gptkbopenai"
OPENAI_MODEL_NAME = "GPT4"
#OPENAI_EMBEDDING_DEPLOYMENT_NAME = os.getenv("OPENAI_EMBEDDING_DEPLOYMENT_NAME")
OPENAI_EMBEDDING_MODEL_NAME = "text-embedding-ada-002"
OPENAI_DEPLOYMENT_VERSION = "2023-03-15-preview"

OPENAI_API_TYPE = "azure"
OPENAI_API_BASE = "https://gptkbopenai.openai.azure.com/"
OPENAI_EMBEDDING_DEPLOYMENT_NAME = "text-embedding-ada-002"

from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.chat_models import AzureChatOpenAI


import os
os.environ["OPENAI_API_TYPE"] = OPENAI_API_TYPE
os.environ["OPENAI_API_BASE"] = OPENAI_API_BASE
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
os.environ["OPENAI_API_VERSION"] = "2023-03-15-preview"

import faiss

# Code adapted from Langchain document comparison toolkit

class DocumentInput(BaseModel):
    question: str = Field()



tools = []
files = [
    {
        "name": "belfast", 
        "path": "C:\\Users\\625050\\OneDrive - Clifford Chance LLP\\Documents\\Projects\\ChatGPT\\LeaseTest\\Belfast.pdf",
    }, 
    {
        "name": "bournemouth", 
        "path": "C:\\Users\\625050\\OneDrive - Clifford Chance LLP\\Documents\\Projects\\ChatGPT\\LeaseTest\\Bournemouth.pdf",
    }
]

llm = AzureChatOpenAI(deployment_name= "GPT4")

for file in files:
    loader = PyPDFLoader(file["path"])
    pages = loader.load_and_split()
    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    docs = text_splitter.split_documents(pages)
    print(docs[0])
    embeddings = OpenAIEmbeddings(deployment=OPENAI_EMBEDDING_DEPLOYMENT_NAME , chunk_size=1)

    #embeddings = OpenAIEmbeddings(model='text-embedding-ada-002',
                              #deployment=OPENAI_DEPLOYMENT_NAME,
                              #openai_api_base=OPENAI_DEPLOYMENT_ENDPOINT,
                              #openai_api_type='azure',
                              #openai_api_key= OPENAI_API_KEY,
                              #chunk_size = 1
    #                          )

    # = OpenAIEmbeddings()
    retriever = FAISS.from_documents(docs, embeddings).as_retriever()
    
    # Wrap retrievers in a Tool
    tools.append(
        Tool(
            args_schema=DocumentInput,
            name=file["name"], 
            description=f"useful when you want to answer questions about {file['name']}",
            func=RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
        )
    )
    
agent = initialize_agent(
    agent=AgentType.OPENAI_FUNCTIONS,
    tools=tools,
    llm=llm,
    verbose=True,
)

agent({"input": "Who are the landlords?"})

Error:
Entering new  chain...
/openai/deployments/GPT4/chat/completions?api-version=2023-03-15-preview None False None None
---------------------------------------------------------------------------
InvalidRequestError                       Traceback (most recent call last)
Cell In[5], line 15
      1 #llm = AzureChatOpenAI()#model_kwargs = {'deployment': "GPT4"},
      2                       #model_name=OPENAI_MODEL_NAME,
      3                       #openai_api_base=OPENAI_DEPLOYMENT_ENDPOINT,
      4                       #openai_api_version=OPENAI_DEPLOYMENT_VERSION,
      5                       #openai_api_key=OPENAI_API_KEY
      6                       #)
      8 agent = initialize_agent(
      9     agent=AgentType.OPENAI_FUNCTIONS,
     10     tools=tools,
     11     llm=llm,
     12     verbose=True,
     13 )
---> 15 agent({"input": "Who are the landlords?"})

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chains\base.py:166, in Chain.__call__(self, inputs, return_only_outputs, callbacks, tags, include_run_info)
    164 except (KeyboardInterrupt, Exception) as e:
    165     run_manager.on_chain_error(e)
--> 166     raise e
    167 run_manager.on_chain_end(outputs)
    168 final_outputs: Dict[str, Any] = self.prep_outputs(
    169     inputs, outputs, return_only_outputs
    170 )

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chains\base.py:160, in Chain.__call__(self, inputs, return_only_outputs, callbacks, tags, include_run_info)
    154 run_manager = callback_manager.on_chain_start(
    155     dumpd(self),
    156     inputs,
    157 )
    158 try:
    159     outputs = (
--> 160         self._call(inputs, run_manager=run_manager)
    161         if new_arg_supported
    162         else self._call(inputs)
    163     )
    164 except (KeyboardInterrupt, Exception) as e:
    165     run_manager.on_chain_error(e)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\agents\agent.py:957, in AgentExecutor._call(self, inputs, run_manager)
    955 # We now enter the agent loop (until it returns something).
    956 while self._should_continue(iterations, time_elapsed):
--> 957     next_step_output = self._take_next_step(
    958         name_to_tool_map,
    959         color_mapping,
    960         inputs,
    961         intermediate_steps,
    962         run_manager=run_manager,
    963     )
    964     if isinstance(next_step_output, AgentFinish):
    965         return self._return(
    966             next_step_output, intermediate_steps, run_manager=run_manager
    967         )

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\agents\agent.py:762, in AgentExecutor._take_next_step(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)
    756 """Take a single step in the thought-action-observation loop.
    757 
    758 Override this to take control of how the agent makes and acts on choices.
    759 """
    760 try:
    761     # Call the LLM to see what to do.
--> 762     output = self.agent.plan(
    763         intermediate_steps,
    764         callbacks=run_manager.get_child() if run_manager else None,
    765         **inputs,
    766     )
    767 except OutputParserException as e:
    768     if isinstance(self.handle_parsing_errors, bool):

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\agents\openai_functions_agent\base.py:209, in OpenAIFunctionsAgent.plan(self, intermediate_steps, callbacks, **kwargs)
    207 prompt = self.prompt.format_prompt(**full_inputs)
    208 messages = prompt.to_messages()
--> 209 predicted_message = self.llm.predict_messages(
    210     messages, functions=self.functions, callbacks=callbacks
    211 )
    212 agent_decision = _parse_ai_message(predicted_message)
    213 return agent_decision

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\base.py:258, in BaseChatModel.predict_messages(self, messages, stop, **kwargs)
    256 else:
    257     _stop = list(stop)
--> 258 return self(messages, stop=_stop, **kwargs)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\base.py:208, in BaseChatModel.__call__(self, messages, stop, callbacks, **kwargs)
    201 def __call__(
    202     self,
    203     messages: List[BaseMessage],
   (...)
    206     **kwargs: Any,
    207 ) -> BaseMessage:
--> 208     generation = self.generate(
    209         [messages], stop=stop, callbacks=callbacks, **kwargs
    210     ).generations[0][0]
    211     if isinstance(generation, ChatGeneration):
    212         return generation.message

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\base.py:102, in BaseChatModel.generate(self, messages, stop, callbacks, tags, **kwargs)
    100 except (KeyboardInterrupt, Exception) as e:
    101     run_manager.on_llm_error(e)
--> 102     raise e
    103 llm_output = self._combine_llm_outputs([res.llm_output for res in results])
    104 generations = [res.generations for res in results]

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\base.py:94, in BaseChatModel.generate(self, messages, stop, callbacks, tags, **kwargs)
     90 new_arg_supported = inspect.signature(self._generate).parameters.get(
     91     "run_manager"
     92 )
     93 try:
---> 94     results = [
     95         self._generate(m, stop=stop, run_manager=run_manager, **kwargs)
     96         if new_arg_supported
     97         else self._generate(m, stop=stop)
     98         for m in messages
     99     ]
    100 except (KeyboardInterrupt, Exception) as e:
    101     run_manager.on_llm_error(e)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\base.py:95, in <listcomp>(.0)
     90 new_arg_supported = inspect.signature(self._generate).parameters.get(
     91     "run_manager"
     92 )
     93 try:
     94     results = [
---> 95         self._generate(m, stop=stop, run_manager=run_manager, **kwargs)
     96         if new_arg_supported
     97         else self._generate(m, stop=stop)
     98         for m in messages
     99     ]
    100 except (KeyboardInterrupt, Exception) as e:
    101     run_manager.on_llm_error(e)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\openai.py:359, in ChatOpenAI._generate(self, messages, stop, run_manager, **kwargs)
    351     message = _convert_dict_to_message(
    352         {
    353             "content": inner_completion,
   (...)
    356         }
    357     )
    358     return ChatResult(generations=[ChatGeneration(message=message)])
--> 359 response = self.completion_with_retry(messages=message_dicts, **params)
    360 return self._create_chat_result(response)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\openai.py:307, in ChatOpenAI.completion_with_retry(self, **kwargs)
    303 @retry_decorator
    304 def _completion_with_retry(**kwargs: Any) -> Any:
    305     return self.client.create(**kwargs)
--> 307 return _completion_with_retry(**kwargs)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\tenacity\__init__.py:289, in BaseRetrying.wraps.<locals>.wrapped_f(*args, **kw)
    287 @functools.wraps(f)
    288 def wrapped_f(*args: t.Any, **kw: t.Any) -> t.Any:
--> 289     return self(f, *args, **kw)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\tenacity\__init__.py:379, in Retrying.__call__(self, fn, *args, **kwargs)
    377 retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs)
    378 while True:
--> 379     do = self.iter(retry_state=retry_state)
    380     if isinstance(do, DoAttempt):
    381         try:

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\tenacity\__init__.py:314, in BaseRetrying.iter(self, retry_state)
    312 is_explicit_retry = fut.failed and isinstance(fut.exception(), TryAgain)
    313 if not (is_explicit_retry or self.retry(retry_state)):
--> 314     return fut.result()
    316 if self.after is not None:
    317     self.after(retry_state)

File c:\Users\625050\Anaconda3\envs\DD\lib\concurrent\futures\_base.py:451, in Future.result(self, timeout)
    449     raise CancelledError()
    450 elif self._state == FINISHED:
--> 451     return self.__get_result()
    453 self._condition.wait(timeout)
    455 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:

File c:\Users\625050\Anaconda3\envs\DD\lib\concurrent\futures\_base.py:403, in Future.__get_result(self)
    401 if self._exception:
    402     try:
--> 403         raise self._exception
    404     finally:
    405         # Break a reference cycle with the exception in self._exception
    406         self = None

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\tenacity\__init__.py:382, in Retrying.__call__(self, fn, *args, **kwargs)
    380 if isinstance(do, DoAttempt):
    381     try:
--> 382         result = fn(*args, **kwargs)
    383     except BaseException:  # noqa: B902
    384         retry_state.set_exception(sys.exc_info())  # type: ignore[arg-type]

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\langchain\chat_models\openai.py:305, in ChatOpenAI.completion_with_retry.<locals>._completion_with_retry(**kwargs)
    303 @retry_decorator
    304 def _completion_with_retry(**kwargs: Any) -> Any:
--> 305     return self.client.create(**kwargs)

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\openai\api_resources\chat_completion.py:25, in ChatCompletion.create(cls, *args, **kwargs)
     23 while True:
     24     try:
---> 25         return super().create(*args, **kwargs)
     26     except TryAgain as e:
     27         if timeout is not None and time.time() > start + timeout:

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\openai\api_resources\abstract\engine_api_resource.py:154, in EngineAPIResource.create(cls, api_key, api_base, api_type, request_id, api_version, organization, **params)
    138 (
    139     deployment_id,
    140     engine,
   (...)
    150     api_key, api_base, api_type, api_version, organization, **params
    151 )
    153 print(url, headers, stream, request_id, request_timeout)
--> 154 response, a, api_key = requestor.request(
    155     "post",
    156     url,
    157     params=params,
    158     headers=headers,
    159     stream=stream,
    160     request_id=request_id,
    161     request_timeout=request_timeout,
    162 )
    164 print(response, a, api_key)
    166 if stream:
    167     # must be an iterator

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\openai\api_requestor.py:230, in APIRequestor.request(self, method, url, params, headers, files, stream, request_id, request_timeout)
    209 def request(
    210     self,
    211     method,
   (...)
    218     request_timeout: Optional[Union[float, Tuple[float, float]]] = None,
    219 ) -> Tuple[Union[OpenAIResponse, Iterator[OpenAIResponse]], bool, str]:
    220     result = self.request_raw(
    221         method.lower(),
    222         url,
   (...)
    228         request_timeout=request_timeout,
    229     )
--> 230     resp, got_stream = self._interpret_response(result, stream)
    231     return resp, got_stream, self.api_key

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\openai\api_requestor.py:624, in APIRequestor._interpret_response(self, result, stream)
    616     return (
    617         self._interpret_response_line(
    618             line, result.status_code, result.headers, stream=True
    619         )
    620         for line in parse_stream(result.iter_lines())
    621     ), True
    622 else:
    623     return (
--> 624         self._interpret_response_line(
    625             result.content.decode("utf-8"),
    626             result.status_code,
    627             result.headers,
    628             stream=False,
    629         ),
    630         False,
    631     )

File c:\Users\625050\Anaconda3\envs\DD\lib\site-packages\openai\api_requestor.py:687, in APIRequestor._interpret_response_line(self, rbody, rcode, rheaders, stream)
    685 stream_error = stream and "error" in resp.data
    686 if stream_error or not 200 <= rcode < 300:
--> 687     raise self.handle_error_response(
    688         rbody, rcode, resp.data, rheaders, stream_error=stream_error
    689     )
    690 return resp

InvalidRequestError: Unrecognized request argument supplied: functions

### Expected behavior

An answer should be generated and no error should be thrown.