Building your own ChatGPT with LangChain and AgentLabs
Tags: python, langchain, openai, chatgpt
Published: 2023-10-27 10:16:08

Conversational agents have emerged as a crucial interface between users and machines.

They facilitate natural interactions, making technology more accessible and user-friendly. 

Among the forerunners of conversational AI, OpenAI's GPT-3 has made waves with its remarkable ability to understand and generate human-like text. 

However, crafting a chatbot with similar capabilities from scratch can be a daunting endeavor, especially for those new to the realm of AI and machine learning. 

But worry not, as in this tutorial, we are about to demystify the process of building your very own ChatGPT using the LangChain framework and [AgentLabs](https://agentlabs.dev) platform.

LangChain provides a robust framework designed to handle Language Models seamlessly, making it a powerful tool for those aiming to build intelligent agents. On the other hand, AgentLabs offers a frontend as a service solution, enabling you to interact with your users without coding any interface.


Note: In this tutorial, we'll use Python as the primary language, but both [LangChain](https://www.langchain.com/) and [AgentLabs](https://agentlabs.dev) support TypeScript.

# Getting started

To get started you will need to install `openai`, `langchain`, `agentlabs-sdk`.

If you use pip:

```bash
pip install openai langchain agentlabs-sdk
```

If you use poetry:

```bash
poetry add openai langchain agentlabs-sdk
```


# Preparing the frontend

We'll start by setting up the user interface with AgentLabs.
It's fairly easy to do:

- sign-in to [https://agentlabs.dev](https://agentlabs.dev)
- create a project
- create an agent and name it ChatGPT
- create a secret key for this agent


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ak711ys58g4oth5zjeur.gif)




## Init the AgentLabs project

Now, we will init AgentLabs with the info they provide to us in our dashboard.

```python
from agentlabs.agent import Agent
from agentlabs.chat import IncomingChatMessage, MessageFormat
from agentlabs.project import Project
import os


alabs = Project(
  project_id="4e51941a-a76c-4593-8921-c60e984aaa4e",
  agentlabs_url="https://chatgpt-langchain.app.agentlabs.dev",
  secret=os.environ['AGENTLABS_SECRET']
)

alabs.connect()
alabs.wait()
```

| Here we add our secret in an environment variable for safety reasons. All the above variables can be found in your AgentLabs console.


## React to user's messages

Your frontend is (almost) ready.

You can now open the URL of your AgentLabs project by clicking "Open my ChatUI".

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lr1azi5qr47yhxqm4457.gif)


However, if you test it now, it won't work.

What we want to do is handle every message sent by the users and pass them to our LLM.

To handle users' messages, we'll use the `on_chat_message` method and pass our handler as an argument.

Let's create a dead simple message handler for now.


```python
def handle_task(message: IncomingChatMessage):
  agent = alabs.agent("7d8ccee9-9316-4634-b8b5-e4628d438d6b")
  agent.typewrite(
    conversation_id=message.conversation_id,
    text="I got your message: " + message.text
  )

alabs.on_chat_message(handle_task)
```

Our handler is pretty straightforward at the moment.
When we get a message, we tell our frontend (our AgentLabs agent) to write it back to the user.

[No worries, we'll make it smarter]

Now we can test our UI to see how it works.

Here's what you should get:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2f5b8ditz05s7jftwkj0.gif)


Here's the full code we got so far:

```python
from agentlabs.agent import Agent
from agentlabs.chat import IncomingChatMessage, MessageFormat
from agentlabs.project import Project
import os


alabs = Project(
  project_id="4e51941a-a76c-4593-8921-c60e984aaa4e",
  agentlabs_url="https://chatgpt-langchain.app.agentlabs.dev",
  secret=os.environ['AGENTLABS_SECRET']
)

def handle_task(message: IncomingChatMessage):
  agent = alabs.agent("7d8ccee9-9316-4634-b8b5-e4628d438d6b")
  agent.typewrite(
    conversation_id=message.conversation_id,
    text="I got your message: " + message.text
  )

alabs.on_chat_message(handle_task)

alabs.connect()
alabs.wait()
```

Now, let's prepare LangChain and make our ChatGPT alive.

# Preparing LangChain

Now we have a frontend, and we need to implement some logic.

Let's import everything we'll need from LangChain SDK.

```python
from typing import Any, Dict, List
from langchain.callbacks.base import BaseCallbackHandler
from langchain.memory import ChatMessageHistory
from langchain.chat_models import ChatOpenAI
from langchain.schema.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage
from langchain.schema.output import LLMResult
```

Now we'll init our LLM and set streaming mode to True so we can stream every token in realtime to our users.

```python
llm = ChatOpenAI(streaming=True)
```

| IMPORTANT: For this model to work, make sure the OPENAI_API_KEY environment variable is set.

Now, let's update our handler so that every time a message comes in, we forward it to GPT.

We'll first create a message List with a first message giving some context to our model and then we'll append the user's message.

```python
def handle_task(message: IncomingChatMessage):
    messages: List[BaseMessage] = [
            SystemMessage(content="You are a general assistant designed to help people with their daily tasks. You should format your answers in markdown format as you see fit."),
            HumanMessage(content=message.text)
    ]
    llm(messages)
```


So far so good! But there is a problem with this code.
You probably noticed we lost our AgentLabs agent.

So, even if this code executes, how do we send the model's response back to our frontend?

Well, LangChain provides a feature named [Callbacks](https://python.langchain.com/docs/modules/callbacks/).

You can extend the `BaseCallbackHandler` provided by LangChain to get real-time updates from your model.

We'll simply define our callback handler and make sure every time the model streams a token we forward it to the user using our AgentLabs agent.

Let's do it!

```python
class AgentLabsStreamingCallback(BaseCallbackHandler):
    def __init__(self, agent: Agent, conversation_id: str):
        super().__init__()
        self.agent = agent
        self.conversation_id = conversation_id

    def on_llm_start(
        self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
    ) -> Any:
        self.stream = self.agent.create_stream(format=MessageFormat.MARKDOWN, conversation_id=self.conversation_id)

    def on_llm_new_token(self, token: str, **kwargs: Any) -> Any:
        self.stream.write(token)

    def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:
        self.stream.end()
```


Now we defined our callback handler, let's instantiate it and use it in our message handler:

```python
def handle_task(message: IncomingChatMessage):
    agent = alabs.agent("7d8ccee9-9316-4634-b8b5-e4628d438d6b")
    messages: List[BaseMessage] = [
            SystemMessage(content="You are a general assistant designed to help people with their daily tasks. You should format your answers in markdown format as you see fit."),
            HumanMessage(content=message.text)
    ]
    callback = AgentLabsStreamingCallback(agent=agent, conversation_id=message.conversation_id)
    llm(messages, callbacks=[callback])
```

### Result


{% youtube https://youtu.be/BZ4ChizoSTI %}

AgentLabs natively supports markdown and plaintext so you can ask ChatGPT to write code.

AgentLabs also supports file upload and many other features that will help you to prototype quickly with LangChain.


## Full code

The full code is hosted [here on Replit](https://replit.com/@kevinpiac/ChatGPT-clone-with-LangChain-and-AgentLabs).


## Limitation

In this version, we only send two messages to our model, so it has no memory.

In [the next tutorial](https://dev.to/kevinpiac/adding-memory-to-your-chatgpt-built-with-langchain-l78), I show you how you can leverage LangChain's memory feature to store every conversation and make your ChatGPT even smarter.


# Conclusion

In conclusion, Langchain and AgentLabs are powerful tools that can be used to prototype conversational AI-based applications.

If you liked this tutorial, feel free to smash the like button and react in the comments below :)