the agent example in the quickstart documentation failed to run
Labels: name: area: agent, name: auto:bug

### Checked other resources

- [X] I added a very descriptive title to this issue.
- [X] I searched the LangChain documentation with the integrated search.
- [X] I used the GitHub search to find a similar question and didn't find it.

### Example Code

```python
import os
from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain import hub
from langchain.agents import create_openai_functions_agent
from langchain.agents import AgentExecutor

os.environ["OPENAI_API_KEY"] = "*************************************"
os.environ["TAVILY_API_KEY"] = "*************************************"


search = TavilySearchResults()
tools = [search]


# Get the prompt to use - you can modify this!
prompt = hub.pull("hwchase17/openai-functions-agent")
llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    temperature=0,
    verbose=True,
)
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

agent_executor.invoke({"input": "what is the weather in SF?"})

```

### Description

Running the example code above will cause an error for both `gpt-3-turbo` and `gpt-4-0613`. The error message is:
```
openai.NotFoundError: Error code: 404 - {'error': {'message': 'Unrecognized request argument supplied: functions (request id: XXXXX)', 'type': 'invalid_request_error', 'param': '', 'code': None}}
```
I searched for this error and found a solution, which involves adding the parameter `api-version="2023-07-01-preview"`. However, I couldn't find a place to input this parameter. After reading through some source code, I finally figured out how:
```python
function_obj = agent.middle[1]
if function_obj.kwargs:
    function_obj.kwargs["extra_query"] = {"api-version": "2023-07-01-preview"}
else:
    function_obj.kwargs = {"extra_query": {"api-version": "2023-07-01-preview"}}
```
This led to another error:
```
openai.BadRequestError: Error code: 400 - {'error': {'message': "Invalid value for 'content': expected a string, got null. (request id: XXXXX", 'type': 'invalid_request_error', 'param': 'messages.[2].content', 'code': None}}
```
After some debugging, I found the reason. Inside `langchain_openai`, there is a function `_convert_message_to_dict`:
```python
elif isinstance(message, AIMessage):
    message_dict = {"role": "assistant", "content": message.content}
    if "function_call" in message.additional_kwargs:
        message_dict["function_call"] = message.additional_kwargs["function_call"]
        # If function call only, content is None not empty string
        if message_dict["content"] == "":
            message_dict["content"] = None
```
This code turns the search result into an `AIMessage` and, for some reason, does not allow the content to be an empty string, so it makes it `None`. However, the OpenAI API does not accept this. To make it work, I had to rewrite the code:
```python
def _convert_message_to_dict(message: BaseMessage) -> dict:
    ...
    elif isinstance(message, AIMessage):
        message_dict = {"role": "assistant", "content": message.content}
        if "function_call" in message.additional_kwargs:
            message_dict["function_call"] = message.additional_kwargs["function_call"]
            # If function call only, content is None not empty string
            # ATTENTION: CHANGE HERE
            # if message_dict["content"] == "":
            #     message_dict["content"] = None
        if "tool_calls" in message.additional_kwargs:
            message_dict["tool_calls"] = message.additional_kwargs["tool_calls"]
            # If tool calls only, content is None not empty string
            if message_dict["content"] == "":
                message_dict["content"] = None
    ...
    return message_dict

def new_create_message_dicts(
    self, messages: List[BaseMessage], stop: Optional[List[str]]
) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]:
    params = self._default_params
    if stop is not None:
        if "stop" in params:
            raise ValueError("`stop` found in both the input and default params.")
        params["stop"] = stop
    message_dicts = [_convert_message_to_dict(m) for m in messages]
    return message_dicts, params
    
llm.Config.extra = Extra.allow
llm._create_message_dicts = partial(new_create_message_dicts, llm)
```
I mean, really? I'm not sure what I did wrong, but it's certainly not easy to make it work. If it's not a bug, I hope to get a simpler and more elegant solution.

### System Info

langchain==0.1.0
langchain-community==0.0.10
langchain-core==0.1.8
langchain-openai==0.0.2
langchainhub==0.1.14

### Related Components

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