{ "cells": [ { "cell_type": "markdown", "id": "c015b59e-1187-4d45-b2af-7b4c5a9512e1", "metadata": {}, "source": [ "# Letta Python Client \n", "Welcome to the Letta tutorial! In this tutorial, we'll go through how to create a basic user-client for Letta and create a custom agent with long term memory. \n", "\n", "Letta runs *agents-as-a-service*, so agents can run independently on a server. For this tutorial, we will run a local version of the client which does not require a server, but still allows you to see some of Letta's capabilities. " ] }, { "cell_type": "code", "execution_count": null, "id": "a34fe313-f63e-4f36-9142-f681431bbb91", "metadata": {}, "outputs": [], "source": [ "!pip install git+https://github.com/cpacker/MemGPT.git@tutorials" ] }, { "cell_type": "markdown", "id": "191c1cf1-03e6-411a-8409-003caa8530f5", "metadata": {}, "source": [ "### Setup your OpenAI API key " ] }, { "cell_type": "code", "execution_count": 6, "id": "23091690-bc50-4fbc-b48d-50b639453e36", "metadata": {}, "outputs": [], "source": [ "import os \n", "\n", "os.environ[\"OPENAI_API_KEY\"] = \"sk-...\"" ] }, { "cell_type": "markdown", "id": "f20ad6c7-9066-45e0-88ac-40920c83cc39", "metadata": {}, "source": [ "## Part 1: Connecting to the Letta Client \n", "\n", "We create a local client which creates a quickstart configuration for OpenAI using the provided `OPENAI_API_KEY`. " ] }, { "cell_type": "code", "execution_count": null, "id": "9b0871a0-42af-4573-a8ba-efb4fe7e5e5a", "metadata": {}, "outputs": [], "source": [ "from letta.client.client import LocalClient\n", "\n", "client = LocalClient(quickstart_option=\"openai\") " ] }, { "cell_type": "markdown", "id": "40666896-0fa2-465e-b51b-57719de30542", "metadata": {}, "source": [ "## Part 2: Create an agent \n", "We'll first start with creating a basic Letta agent. " ] }, { "cell_type": "code", "execution_count": null, "id": "fb90f12b-acd7-4877-81e8-0e7b9eb4bd9b", "metadata": {}, "outputs": [], "source": [ "basic_agent = client.create_agent(\n", " name=\"basic_agent\", \n", ")\n", "print(f\"Created agent: {basic_agent.name}\")" ] }, { "cell_type": "markdown", "id": "94d14102-3ef8-40fe-b32e-c77d0b8df311", "metadata": {}, "source": [ "We can now send messages from the user to the agent by specifying the `agent_id`: " ] }, { "cell_type": "code", "execution_count": null, "id": "3cbfef36-76f0-4f0b-990a-5d8409a676d7", "metadata": {}, "outputs": [], "source": [ "from letta.client.utils import pprint \n", "\n", "response = client.user_message(agent_id=basic_agent.id, message=\"hello\") \n", "pprint(response.messages)" ] }, { "cell_type": "markdown", "id": "b24d048e-f3cc-4830-aaa2-5e590d652bd9", "metadata": {}, "source": [ "### Adding Personalization\n", "We can now create a more customized agent, but specifying a custom `human` and `persona` field. \n", "* The *human* specifies the personalization information about the user interacting with the agent \n", "* The *persona* specifies the behavior and personality of the event\n", "\n", "What makes Letta unique is that the starting *persona* and *human* can change over time as the agent gains new information, enabling it to have evolving memory. We'll see an example of this later in the tutorial." ] }, { "cell_type": "code", "execution_count": null, "id": "3ec35979-9102-4ea7-926e-ea7ccd501ceb", "metadata": {}, "outputs": [], "source": [ "# TODO: feel free to change the human and person to what you'd like \n", "persona = \\\n", "\"\"\"\n", "You are a friendly and helpful agent!\n", "\"\"\"\n", "\n", "human = \\\n", "\"\"\"\n", "I am an Accenture consultant with many specializations. My name is Sarah.\n", "\"\"\"\n", "\n", "custom_agent = client.create_agent(\n", " name=\"custom_agent\", \n", " human=human, \n", " persona=persona\n", ")" ] }, { "cell_type": "markdown", "id": "63a9a61b-58c9-4d09-a4f7-48233c72c340", "metadata": {}, "source": [ "### Viewing memory \n", "You can access the agent's memories through the client. There are two type of memory, *core* and *archival* memory: \n", "1. Core memory stores short-term memories in the LLM's context \n", "2. Archival memory stores long term memories in a vector database\n", "\n", "Core memory is divided into a \"human\" and \"persona\" section. You can see the agent's memories about the human below: " ] }, { "cell_type": "code", "execution_count": null, "id": "b0d1840a-05ee-47c1-b5f5-89faafd96e7c", "metadata": {}, "outputs": [], "source": [ "print(client.get_agent_memory(agent_id=custom_agent.id)[\"core_memory\"][\"human\"])" ] }, { "cell_type": "markdown", "id": "95c8a058-5d67-45b7-814b-38bb67c9acf3", "metadata": {}, "source": [ "### Evolving memory \n", "Letta agents have long term memory, and can evolve what they store in their memory over time. In the example below, we make a correction to the previously provided information. See how the agent processes this new information. " ] }, { "cell_type": "code", "execution_count": null, "id": "7e58e685-579e-4a0d-bba7-41976ea7f469", "metadata": {}, "outputs": [], "source": [ "response = client.user_message(agent_id=custom_agent.id, message=\"Actually, my name is Charles\") \n", "pprint(response.messages)" ] }, { "cell_type": "markdown", "id": "af2a2dd6-925e-49b2-ab01-bf837f33b26c", "metadata": {}, "source": [ "Now lets see what the agent's memory looks like again: " ] }, { "cell_type": "code", "execution_count": null, "id": "41ef4aaa-4a48-44bb-8944-855f30725d6d", "metadata": {}, "outputs": [], "source": [ "print(client.get_agent_memory(agent_id=custom_agent.id)[\"core_memory\"][\"human\"])" ] }, { "cell_type": "markdown", "id": "66da949b-1084-4b87-b77c-6cbd4a822b34", "metadata": {}, "source": [ "## 🎉 Congrats, you're done with day 1 of Letta! \n", "For day 2, we'll go over how to connect *data sources* to Letta to run RAG agents. " ] } ], "metadata": { "kernelspec": { "display_name": "letta", "language": "python", "name": "letta" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.2" } }, "nbformat": 4, "nbformat_minor": 5 }