This will go over how to get started building an agent.
We will use a LangChain agent class, but show how to customize it to give it specific context.
We will then define custom tools, and then run it all in the standard LangChain AgentExecutor.

### Set up the agent

We will use the OpenAIFunctionsAgent.
This is easiest and best agent to get started with.
It does however require usage of ChatOpenAI models.
If you want to use a different language model, we would recommend using the [ReAct](/docs/modules/agents/agent_types/react) agent.

For this guide, we will construct a custom agent that has access to a custom tool.
We are choosing this example because we think for most use cases you will NEED to customize either the agent or the tools.
The tool we will give the agent is a tool to calculate the length of a word.
This is useful because this is actually something LLMs can mess up due to tokenization.
We will first create it WITHOUT memory, but we will then show how to add memory in.
Memory is needed to enable conversation.

First, let's load the language model we're going to use to control the agent.
```python
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(temperature=0)
```

Next, let's define some tools to use.
Let's write a really simple Python function to calculate the length of a word that is passed in.



```python
from langchain.agents import tool

@tool
def get_word_length(word: str) -> int:
    """Returns the length of a word."""
    return len(word)

tools = [get_word_length]
```

Now let us create the prompt.
We can use the `OpenAIFunctionsAgent.create_prompt` helper function to create a prompt automatically.
This allows for a few different ways to customize, including passing in a custom SystemMessage, which we will do.

```python
from langchain.schema import SystemMessage
from langchain.agents import OpenAIFunctionsAgent
system_message = SystemMessage(content="You are very powerful assistant, but bad at calculating lengths of words.")
prompt = OpenAIFunctionsAgent.create_prompt(system_message=system_message)
```

Putting those pieces together, we can now create the agent.

```python
agent = OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt)
```

Finally, we create the AgentExecutor - the runtime for our agent.

```python
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
```

Now let's test it out!


```python
agent_executor.run("how many letters in the word educa?")
```

<CodeOutputBlock lang="python">

```
    
    
    > Entering new AgentExecutor chain...

    Invoking: `get_word_length` with `{'word': 'educa'}`

    5

    There are 5 letters in the word "educa".

    > Finished chain.

    'There are 5 letters in the word "educa".'
```

</CodeOutputBlock>

This is great - we have an agent!
However, this agent is stateless - it doesn't remember anything about previous interactions.
This means you can't ask follow up questions easily.
Let's fix that by adding in memory.

In order to do this, we need to do two things:

1. Add a place for memory variables to go in the prompt
2. Add memory to the AgentExecutor (note that we add it here, and NOT to the agent, as this is the outermost chain)

First, let's add a place for memory in the prompt.
We do this by adding a placeholder for messages with the key `"chat_history"`.

```python
from langchain.prompts import MessagesPlaceholder

MEMORY_KEY = "chat_history"
prompt = OpenAIFunctionsAgent.create_prompt(
    system_message=system_message,
    extra_prompt_messages=[MessagesPlaceholder(variable_name=MEMORY_KEY)]
)
```

Next, let's create a memory object.
We will do this by using `ConversationBufferMemory`.
Importantly, we set `memory_key` also equal to `"chat_history"` (to align it with the prompt) and set `return_messages` (to make it return messages rather than a string).

```python
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key=MEMORY_KEY, return_messages=True)
```

We can then put it all together!

```python
agent = OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, memory=memory, verbose=True)
agent_executor.run("how many letters in the word educa?")
agent_executor.run("is that a real word?")
```
