Julep is a platform for creating AI agents that remember past interactions and can perform complex tasks. It offers long-term memory and manages multi-step processes.
Julep enables the creation of multi-step tasks incorporating decision-making, loops, parallel processing, and integration with numerous external tools and APIs.
While many AI applications are limited to simple, linear chains of prompts and API calls with minimal branching, Julep is built to handle more complex scenarios.
It supports:
Intricate, multi-step processes
Dynamic decision-making
Parallel execution
[!TIP] Imagine you want to build an AI agent that can do more than just answer simple questions—it needs to handle complex tasks, remember past interactions, and maybe even use other tools or APIs. That's where Julep comes in.
Quick Example
Imagine a Research AI agent that can do the following:
Take a topic,
Come up with 100 search queries for that topic,
Perform those web searches in parallel,
Summarize the results,
Send the summary to Discord
In Julep, this would be a single task under 80 lines of code and run fully managed all on its own. All of the steps are executed on Julep's own servers and you don't need to lift a finger. Here's a working example:
name:Research Agent# Optional: Define the input schema for the taskinput_schema:type:objectproperties:topic:type:stringdescription:The main topic to research# Define the tools that the agent can usetools: - name:web_searchtype:integrationintegration:provider:bravesetup:api_key:"YOUR_BRAVE_API_KEY" - name:discord_webhooktype:api_callapi_call:url:"YOUR_DISCORD_WEBHOOK_URL"method:POSTheaders:Content-Type:application/json# Special variables:# - inputs: for accessing the input to the task# - outputs: for accessing the output of previous steps# - _: for accessing the output of the previous step# Define the main workflowmain: - prompt: - role:systemcontent:>- You are a research assistant. Generate 100 diverse search queries related to the topic: {{inputs[0].topic}} Write one query per line.unwrap:true# Evaluate the search queries using a simple python expression - evaluate:search_queries:"_.split('\n')"# Run the web search in parallel for each query - over:"_.search_queries"map:tool:web_searcharguments:query:"_"parallelism:100# Collect the results from the web search - evaluate:results:"'\n'.join([item.result for item in _])"# Summarize the results - prompt: - role:systemcontent:> You are a research summarizer. Create a comprehensive summary of the following research results on the topic {{inputs[0].topic}}.
The summary should be well-structured, informative, and highlight key findings and insights: {{_.results}}unwrap:true# Send the summary to Discord - tool:discord_webhookarguments:content:> **Research Summary for {{inputs[0].topic}}** {{_}}
[!TIP] Julep is really useful when you want to build AI agents that can maintain context and state over long-term interactions. It's great for designing complex, multi-step workflows and integrating various tools and APIs directly into your agent's processes.
In this example, Julep will automatically manage parallel executions, retry failed steps, resend API requests, and keep the tasks running reliably until completion.
Key Features
🧠 Persistent AI Agents: Remember context and information over long-term interactions.
💾 Stateful Sessions: Keep track of past interactions for personalized responses.
🔄 Multi-Step Tasks: Build complex, multi-step processes with loops and decision-making.
⏳ Task Management: Handle long-running tasks that can run indefinitely.
🛠️ Built-in Tools: Use built-in tools and external APIs in your tasks.
🔧 Self-Healing: Julep will automatically retry failed steps, resend messages, and generally keep your tasks running smoothly.
📚 RAG: Use Julep's document store to build a system for retrieving and using your own data.
Julep is ideal for applications that require AI use cases beyond simple prompt-response models.
Why Julep vs. LangChain?
Different Use Cases
Think of LangChain and Julep as tools with different focuses within the AI development stack.
LangChain is great for creating sequences of prompts and managing interactions with AI models. It has a large ecosystem with lots of pre-built integrations, which makes it convenient if you want to get something up and running quickly. LangChain fits well with simple use cases that involve a linear chain of prompts and API calls.
Julep, on the other hand, is more about building persistent AI agents that can remember things over long-term interactions. It shines when you need complex tasks that involve multiple steps, decision-making, and integration with various tools or APIs directly within the agent's process. It's designed from the ground up to manage persistent sessions and complex tasks.
Use Julep if you imagine building a complex AI assistant that needs to:
Keep track of user interactions over days or weeks.
Perform scheduled tasks, like sending daily summaries or monitoring data sources.
Make decisions based on prior interactions or stored data.
Interact with multiple external services as part of its task.
Then Julep provides the infrastructure to support all that without you having to build it from scratch.
Different Form Factor
Julep is a platform that includes a language for describing tasks, a server for running those tasks, and an SDK for interacting with the platform. To build something with Julep, you write a description of the task in YAML, and then run the task in the cloud.
Julep is built for heavy-lifting, multi-step, and long-running tasks and there's no limit to how complex the task can be.
LangChain is a library that includes a few tools and a framework for building linear chains of prompts and tools. To build something with LangChain, you typically write Python code that configures and runs the model chains you want to use.
LangChain might be sufficient and quicker to implement for simple use cases that involve a linear chain of prompts and API calls.
In Summary
Use LangChain when you need to manage AI model interactions and prompt sequences in a stateless or short-term context.
Choose Julep when you need a robust framework for stateful agents with advanced task capabilities, persistent sessions, and complex task management.
Installation
To get started with Julep, install it using npm or pip:
While we are in beta, you can also reach out on Discord to get rate limits lifted on your API key.
[!TIP] 💻 Are you a show me the code!™ kind of person? We have created a ton of cookbooks for you to get started with. Check out the cookbooks to browse through examples.
💡 There's also lots of ideas that you can build on top of Julep. Check out the list of ideas to get some inspiration.
Python Quick Start 🐍
Step 1: Create an Agent
import yamlfrom julep import Julep # or AsyncJulepclient =Julep(api_key="your_julep_api_key", environment=“dev”)agent = client.agents.create( name="Storytelling Agent", model="gpt-4o", about="You are a creative storytelling agent that can craft engaging stories and generate comic panels based on ideas.",
)# 🛠️ Add an image generation tool (DALL·E) to the agentclient.agents.tools.create( agent_id=agent.id, name="image_generator", description="Use this tool to generate images based on descriptions.", integration={"provider": "dalle","method": "generate_image","setup": {"api_key": "your_openai_api_key", }, },)
Step 2: Create a Task that generates a story and comic strip
Let's define a multi-step task to create a story and generate a paneled comic strip based on an input idea:
# 📋 Task# Create a task that takes an idea and creates a story and a 4-panel comic striptask_yaml ="""name: Story and Comic Creatordescription: Create a story based on an idea and generate a 4-panel comic strip illustrating the story.main: # Step 1: Generate a story and outline into 4 panels - prompt: - role: system content: You are {{agent.name}}. {{agent.about}} - role: user content: > Based on the idea '{{_.idea}}', write a short story suitable for a 4-panel comic strip. Provide the story and a numbered list of 4 brief descriptions for each panel illustrating key moments in the story.
unwrap: true # Step 2: Extract the panel descriptions and story - evaluate: story: _.split('1. ')[0].strip() panels: re.findall(r'\\d+\\.\\s*(.*?)(?=\\d+\\.\\s*|$)', _) # Step 3: Generate images for each panel using the image generator tool - foreach: in: _.panels do: tool: image_generator arguments: description: _ # Step 4: Generate a catchy title for the story - prompt: - role: system content: You are {{agent.name}}. {{agent.about}} - role: user content: > Based on the story below, generate a catchy title. Story: {{outputs[1].story}} unwrap: true # Step 5: Return the story, the generated images, and the title - return: title: outputs[3] story: outputs[1].story comic_panels: "[output.image.url for output in outputs[2]]""""task = client.tasks.create( agent_id=agent.id,**yaml.safe_load(task_yaml))
Step 3: Execute the Task
# 🚀 Execute the task with an input ideaexecution = client.executions.create( task_id=task.id, input={"idea": "A cat who learns to fly"})# 🎉 Watch as the story and comic panels are generatedfor transition in client.executions.transitions.stream(execution_id=execution.id):print(transition)# 📦 Once the execution is finished, retrieve the resultsresult = client.executions.get(execution_id=execution.id)
Step 4: Chat with the Agent
Start an interactive chat session with the agent:
session = client.sessions.create(agent_id=agent.id)# 💬 Send messages to the agentwhile (message :=input("Enter a message: ")) !="quit": response = client.sessions.chat( session_id=session.id, message=message, )print(response)
import { Julep } from"@julep/sdk";import yaml from"js-yaml";constclient=newJulep({ apiKey:"your_julep_api_key",environment:“dev” });asyncfunctioncreateAgent() {constagent=awaitclient.agents.create({ name:"Storytelling Agent", model:"gpt-4", about: "You are a creative storytelling agent that can craft engaging stories and generate comic panels based on ideas.",
});// 🛠️ Add an image generation tool (DALL·E) to the agentawaitclient.agents.tools.create(agent.id, { name:"image_generator", description:"Use this tool to generate images based on descriptions.", integration: { provider:"dalle", method:"generate_image", setup: { api_key:"your_openai_api_key", }, }, });return agent;}
Step 2: Create a Task that generates a story and comic strip
consttaskYaml=`name: Story and Comic Creatordescription: Create a story based on an idea and generate a 4-panel comic strip illustrating the story.main: # Step 1: Generate a story and outline into 4 panels - prompt: - role: system content: You are {{agent.name}}. {{agent.about}} - role: user content: > Based on the idea '{{_.idea}}', write a short story suitable for a 4-panel comic strip. Provide the story and a numbered list of 4 brief descriptions for each panel illustrating key moments in the story.
unwrap: true # Step 2: Extract the panel descriptions and story - evaluate: story: _.split('1. ')[0].trim() panels: _.match(/\\d+\\.\\s*(.*?)(?=\\d+\\.\\s*|$)/g) # Step 3: Generate images for each panel using the image generator tool - foreach: in: _.panels do: tool: image_generator arguments: description: _ # Step 4: Generate a catchy title for the story - prompt: - role: system content: You are {{agent.name}}. {{agent.about}} - role: user content: > Based on the story below, generate a catchy title. Story: {{outputs[1].story}} unwrap: true # Step 5: Return the story, the generated images, and the title - return: title: outputs[3] story: outputs[1].story comic_panels: outputs[2].map(output => output.image.url)`;asyncfunctioncreateTask(agent) {consttask=awaitclient.tasks.create(agent.id,yaml.load(taskYaml));return task;}
Step 3: Execute the Task
asyncfunctionexecuteTask(task) {constexecution=awaitclient.executions.create(task.id, { input: { idea:"A cat who learns to fly" }, });// 🎉 Watch as the story and comic panels are generatedforawait (consttransitionofclient.executions.transitions.stream(execution.id )) {console.log(transition); }// 📦 Once the execution is finished, retrieve the resultsconstresult=awaitclient.executions.get(execution.id);return result;}
Step 4: Chat with the Agent
asyncfunctionchatWithAgent(agent) {constsession=awaitclient.sessions.create({ agent_id:agent.id });// 💬 Send messages to the agentconstrl=readline.createInterface({ input:process.stdin, output:process.stdout, });constchat=async () => {rl.question("Enter a message (or 'quit' to exit): ",async (message) => {if (message.toLowerCase() ==="quit") {rl.close();return; }constresponse=awaitclient.sessions.chat(session.id, { message });console.log(response);chat(); }); };chat();}// Run the exampleasyncfunctionrunExample() {constagent=awaitcreateAgent();consttask=awaitcreateTask(agent);constresult=awaitexecuteTask(task);console.log("Task Result:", result);awaitchatWithAgent(agent);}runExample().catch(console.error);
[!TIP] You can find the full Node.js example here.
Components
Julep is made up of the following components:
Julep Platform: The Julep platform is a cloud service that runs your workflows. It includes a language for describing workflows, a server for running those workflows, and an SDK for interacting with the platform.
Julep SDKs: Julep SDKs are a set of libraries for building workflows. There are SDKs for Python and JavaScript, with more on the way.
Julep API: The Julep API is a RESTful API that you can use to interact with the Julep platform.
Mental Model
Think of Julep as a platform that combines both client-side and server-side components to help you build advanced AI agents. Here's how to visualize it:
Your Application Code:
You use the Julep SDK in your application to define agents, tasks, and workflows.
The SDK provides functions and classes that make it easy to set up and manage these components.
Julep Backend Service:
The SDK communicates with the Julep backend over the network.
The backend handles execution of tasks, maintains session state, stores documents, and orchestrates workflows.
Integration with Tools and APIs:
Within your workflows, you can integrate external tools and services.
The backend facilitates these integrations, so your agents can, for example, perform web searches, access databases, or call third-party APIs.
In simpler terms:
Julep is a platform for building stateful AI agents.
You use the SDK (like a toolkit) in your code to define what your agents do.
The backend service (which you can think of as the engine) runs these definitions, manages state, and handles complexity.
Concepts
Julep is built on several key technical components that work together to create powerful AI workflows:
Agents: AI-powered entities backed by large language models (LLMs) that execute tasks and interact with users.
Users: Entities that interact with agents through sessions.
Sessions: Stateful interactions between agents and users, maintaining context across multiple exchanges.
Tasks: Multi-step, programmatic workflows that agents can execute, including various types of steps like prompts, tool calls, and conditional logic.
Tools: Integrations that extend an agent's capabilities, including user-defined functions, system tools, or third-party API integrations.
Documents: Text or data objects associated with agents or users, vectorized and stored for semantic search and retrieval.
Executions: Instances of tasks that have been initiated with specific inputs, with their own lifecycle and state machine.
For a more detailed explanation of these concepts and their interactions, please refer to our Concepts Documentation.
Understanding Tasks
Tasks are the core of Julep's workflow system. They allow you to define complex, multi-step AI workflows that your agents can execute. Here's a brief overview of task components:
Name and Description: Each task has a unique name and description for easy identification.
Main Steps: The core of a task, defining the sequence of actions to be performed.
Tools: Optional integrations that extend the capabilities of your agent during task execution.
Types of Workflow Steps
Tasks in Julep can include various types of steps, allowing you to create complex and powerful workflows. Here's an overview of the available step types, organized by category:
Common Steps
Prompt: Send a message to the AI model and receive a response.
- prompt:"Analyze the following data: {{data}}"
Tool Call: Execute an integrated tool or API.
- tool:web_searcharguments:query:"Latest AI developments"
Evaluate: Perform calculations or manipulate data.
Error: Handle errors by specifying an error message.
- error:"Invalid input provided"
Each step type serves a specific purpose in building sophisticated AI workflows. This categorization helps in understanding the various control flows and operations available in Julep tasks.
Advanced Features
Julep offers a range of advanced features to enhance your AI workflows:
Adding Tools to Agents
Extend your agent's capabilities by integrating external tools and APIs:
client.agents.tools.create( agent_id=agent.id, name="web_search", description="Search the web for information.", integration={"provider": "brave","method": "search","setup": {"api_key": "your_brave_api_key"}, },)
Managing Sessions and Users
Julep provides robust session management for persistent interactions:
session = client.sessions.create( agent_id=agent.id, user_id=user.id, context_overflow="adaptive")# Continue conversation in the same sessionresponse = client.sessions.chat( session_id=session.id, messages=[ {"role": "user","content": "Follow up on the previous conversation." } ])
Document Integration and Search
Easily manage and search through documents for your agents:
# Upload a documentdocument = client.agents.docs.create( title="AI advancements", content="AI is changing the world...", metadata={"category": "research_paper"})# Search documentsresults = client.agents.docs.search( text="AI advancements", metadata_filter={"category": "research_paper"})
Julep supports various integrations that extend the capabilities of your AI agents. Here's a list of available integrations and their supported arguments:
Brave Search
setup:api_key:string# The API key for Brave Searcharguments:query:string# The search query for searching with Braveoutput:result:string# The result of the Brave Search
BrowserBase
setup:api_key:string# The API key for BrowserBaseproject_id:string# The project ID for BrowserBasesession_id:string# (Optional) The session ID for BrowserBasearguments:urls:list[string]# The URLs for loading with BrowserBaseoutput:documents:list# The documents loaded from the URLs
Email
setup:host:string# The host of the email serverport:integer# The port of the email serveruser:string# The username of the email serverpassword:string# The password of the email serverarguments:to:string# The email address to send the email tofrom:string# The email address to send the email fromsubject:string# The subject of the emailbody:string# The body of the emailoutput:success:boolean# Whether the email was sent successfully
Spider
setup:spider_api_key:string# The API key for Spiderarguments:url:string# The URL for which to fetch datamode:string# The type of crawlers (default: "scrape")params:dict# (Optional) The parameters for the Spider APIoutput:documents:list# The documents returned from the spider
Weather
setup:openweathermap_api_key:string# The API key for OpenWeatherMaparguments:location:string# The location for which to fetch weather dataoutput:result:string# The weather data for the specified location
Wikipedia
arguments:query:string# The search query stringload_max_docs:integer# Maximum number of documents to load (default: 2)output:documents:list# The documents returned from the Wikipedia search
These integrations can be used within your tasks to extend the capabilities of your AI agents. For more detailed information on how to use these integrations in your workflows, please refer to our Integrations Documentation.