Setup Your Development Environment

Follow these steps to set up Persona locally and start building.

Clone the repository and install dependencies.

Ensure you have Docker and Docker Compose installed on your machine.

Configure Environment Variables

Create a .env file in the root directory based on the provided example:

cp .env.example .env

Edit the .env file to include your specific configurations:

URI_NEO4J=neo4j://neo4j:7687
USER_NEO4J=neo4j
PASSWORD_NEO4J=your_secure_password

NEO4J_AUTH=neo4j/your_secure_password

OPENAI_API_KEY=your_openai_api_key

Run the Docker Containers

docker compose up --build -d

This command sets up the FastAPI backend and Neo4j graph database.

FastAPI will be available at http://localhost:8000

Neo4j will be available at bolt://localhost:7687. Neo4j Browser will be available at http://localhost:7474.

You can change the ports in the docker compose file if you are running other services on your system.

Interact with the API

Persona exposes a set of RESTful APIs to interact with user knowledge graphs. Get started with basic endpoints to create a user, ingest data, and perform RAG queries.

Create a New User

Endpoint:

POST /api/v1/users

Request Body:

{
  "user_id": "maya"
}

Ingest User Data

Ingest API is designed to be used with unstructured data inherently. In the backend Persona uses a combination of LLMs and Graph Schema to construct the user’s graph. So you can ingest data as a string, following any format, and Persona will do its best to understand and store it in the graph.

Persona is primarily designed to take in user interaction logs as strings, but can work with conversational data, or any other unstructured data. For now, we will use a simple text input.

Endpoint:

POST /api/v1/ingest/{user_id}

Request Body:

{
  "content": "Maya is a software engineer who loves hiking and photography."
}

Perform a RAG Query

Persona can answer questions based on user’s knowledge graph. This is a RAG interface to user’s data.

Endpoint:

POST /api/v1/rag/{user_id}/query

Request Body:

{
  "query": "What are Maya's hobbies?"
}

Response:

{
  "answer": "Maya enjoys hiking and photography."
}

Learn Anything - Ask Anything

Persona can be configured to understand custom attributes of a user for your specific use case. There are two interfaces to interact with the user’s graph. Learn and Ask.

Learn Interface

Learn interface gives you a way to instruct Persona on how to construct the graph, and what properties to focus on. Define a schema and Persona will use it for it’s next ingestion cycle.

A learning schema consists of:

  • Name: Identifier for the schema
  • Description: Purpose of the schema
  • Attributes: Node properties to extract
  • Relationships: Edge types to identify

Below is an example of a learning schema for a user’s fitness motivation.

Endpoint:

POST /api/v1/learn

Request Body:

{
  "user_id": "maya",
  "graph_schema": {
    "name": "Fitness Motivation",
    "description": "Understanding user's fitness motivation and goals",
    "attributes": [
      "FAVORITE_ACTIVITY",
      "MOTIVATION",
      "AVAILABILITY",
      "INSPIRATIONAL_FIGURES",
      "WORKS",
      "DOESNT_WORK"
    ],
    "relationships": [
      "ENJOYS",
      "DISLIKES",
      "AVOID"
    ]
  },
  "description": "Understanding what type of physical activity the user enjoys, and what is their understanding of fitness."
}

The graph will now be updated with the new schema, and future ingestion will be sensitive to record this data in the graph. You can give as many learning schemas as you want, and they will all be applied to the next ingestion cycle.

Querying this data will now be easier and cost effective with Cypher queries instead of RAG.

Ask Interface

ASK interace allows you to create custom APIs to answer questions based on the user’s graph. You can define a fixed question for your app, and an example output schema for the response.

You can run this as a one time query to generate new insights about your user, or as a recurring query. This will be served as a RESTful API for your app to use. The response object will follow the example output schema.

Endpoint:

POST /api/v1/ask

Request Body:

{
  "user_id": "maya",
  "question": "What are this user's top 3 favorite outdoor activities?",
  "context": {
    "top_activities": [
      "running",
      "biking",
      "social_fitness"
    ],
    "analysis": [
      {
        "primary_activity": "running",
        "evidence": "Talks about running a lot. Has run multiple marathons."
      }
    ]
  }
}

Response:

{
  "top_activities": ["hiking", "biking", "social_fitness"],
  "analysis": [
    {
      "primary_activity": "hiking",
      "evidence": "Talks about hiking a lot, posts pictures of hikes. Memorable moments with friends and family. Childhood memories of hiking through Muir Woods."
    }
  ]
}

Ensure that you define the question and the example output schema in the same context that your graph and app is built for.

This is prone to hallucinations if there are absolutely no themes related to graph. Avoid asking about topics that are not remotely related to the graph or your app.

There are better ways to implement this, and we are working on it. Meanwhile if you have any ideas, contributions are welcome.

Conclusion

You’ve now set up Persona and performed a basic RAG query. From here, you can explore the API documentation, architecture, and contribute to the project.

Welcome to the Persona community! 🚀