Skip to content

Commit

Permalink
docs: add Conceptual Guides
Browse files Browse the repository at this point in the history
work on #12
  • Loading branch information
bsorrentino committed Aug 29, 2024
1 parent c334c5d commit 33ba752
Show file tree
Hide file tree
Showing 40 changed files with 11,867 additions and 9 deletions.
50 changes: 50 additions & 0 deletions core-jdk8/src/site/markdown/concepts/agentic_concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

# Common Agentic Patterns

## Structured Output

> _TO DO _
## Tool calling

> _TO DO _
## Memory

> _TO DO _
## Human-in-the-loop

> _TO DO _
### Approval

> _TO DO _
### Wait for input

> _TO DO _
### Edit agent actions

> _TO DO _
### Time travel

> _TO DO _
## Multi-agent

> _TO DO _
## Planning

> _TO DO _
## Reflection

> _TO DO _
## ReAct Agent

> _TO DO _
91 changes: 91 additions & 0 deletions core-jdk8/src/site/markdown/concepts/agentic_concepts_BAK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Common Agentic Patterns

## Structured Output

It's pretty common to want LLMs inside nodes to return structured output when building agents. This is because that structured output can often be used to route to the next step (e.g. choose between two different edges) or update specific keys of the state.

Since LangGraph nodes can be arbitrary JavaScript/TypeScript functions, you can do this however you want. If you want to use LangChain, [this how-to guide](https://js.langchain.com/v0.2/docs/how_to/structured_output/) is a starting point.

## Tool calling

It's extremely common to want agents to do tool calling. Tool calling refers to choosing from several available tools, and specifying which ones to call and what the inputs should be. This is extremely common in agents, as you often want to let the LLM decide which tools to call and then call those tools.

Since LangGraph nodes can be arbitrary JavaScript/TypeScript functions, you can do this however you want. If you want to use LangChain, [this how-to guide](https://js.langchain.com/v0.2/docs/how_to/tool_calling/) is a starting point.

## Memory

Memory is a key concept to agentic applications. Memory is important because end users often expect the application they are interacting with remember previous interactions. The most simple example of this is chatbots - they clearly need to remember previous messages in a conversation.

LangGraph is perfectly suited to give you full control over the memory of your application. With user defined [`State`](./low_level.md#state) you can specify the exact schema of the memory you want to retain. With [checkpointers](./low_level.md#checkpointer) you can store checkpoints of previous interactions and resume from there in follow up interactions.

See [this guide](../how-tos/persistence.ipynb) for how to add memory to your graph.

## Human-in-the-loop

Agentic systems often require some human-in-the-loop (or "on-the-loop") interaction patterns. This is because agentic systems are still not super reliable, so having a human involved is required for any sensitive tasks/actions. These are all easily enabled in LangGraph, largely due to [checkpointers](./low_level.md#checkpointer). The reason a checkpointer is necessary is that a lot of these interaction patterns involve running a graph up until a certain point, waiting for some sort of human feedback, and then continuing. When you want to "continue" you will need to access the state of the graph previous to getting interrupted, and checkpointers are a built in, highly convenient way to do that.

There are a few common human-in-the-loop interaction patterns we see emerging.

### Approval

A basic one is to have the agent wait for approval before executing certain tools. This may be all tools, or just a subset of tools. This is generally recommend for more sensitive actions (like writing to a database). This can easily be done in LangGraph by setting a [breakpoint](./low_level.md#breakpoints) before specific nodes.

See [this guide](../how-tos/breakpoints.ipynb) for how do this in LangGraph.

### Wait for input

A similar one is to have the agent wait for human input. This can be done by:

1. Create a node specifically for human input
2. Add a breakpoint before the node
3. Get user input
4. Update the state with that user input, acting as that node
5. Resume execution

See [this guide](../how-tos/wait-user-input.ipynb) for how do this in LangGraph.

### Edit agent actions

This is a more advanced interaction pattern. In this interaction pattern the human can actually edit some of the agent's previous decisions. This can be done either during the flow (after a [breakpoint](./low_level.md#breakpoints), part of the [approval](#approval) flow) or after the fact (as part of [time-travel](#time-travel))

See [this guide](../how-tos/edit-graph-state.ipynb) for how do this in LangGraph.

### Time travel

This is a pretty advanced interaction pattern. In this interaction pattern, the human can look back at the list of previous checkpoints, find one they like, optionally [edit it](#edit-agent-actions), and then resume execution from there.

See [this guide](../how-tos/time-travel.ipynb) for how to do this in LangGraph.

## Multi-agent

A term you may have heard is "multi-agent" architectures. What exactly does this mean?

Given that it is hard to even define an "agent", it's almost impossible to exactly define a "multi-agent" architecture. When most people talk about a multi-agent architecture, they typically mean a system where there are multiple different LLM-based systems. These LLM-based systems can be as simple as a prompt and an LLM call, or as complex as a [ReAct agent](#react-agent).

The big question in multi-agent systems is how they communicate. This involves both the schema of how they communicate, as well as the sequence in which they communicate. LangGraph is perfect for orchestrating these types of systems. It allows you to define multiple agents (each one is a node) an arbitrary state (to encapsulate the schema of how they communicate) as well as the edges (to control the sequence in which they communicate).

## Planning

One of the big things that agentic systems struggle with is long term planning. A common technique to overcome this is to have an explicit planning this. This generally involves calling an LLM to come up with a series of steps to execute. From there, the system then tries to execute the series of tasks (this could use a sub-agent to do so). Optionally, you can revisit the plan after each step and update it if needed.

## Reflection

Agents often struggle to produce reliable results. Therefore, it can be helpful to check whether the agent has completed a task correctly or not. If it has - then you can finish. If it hasn't - then you can take the feedback on why it's not correct and pass it back into another iteration of the agent.

This "reflection" step often uses an LLM, but doesn't have to. A good example of where using an LLM may not be necessary is in coding, when you can try to compile the generated code and use any errors as the feedback.

## ReAct Agent

One of the most common agent architectures is what is commonly called the ReAct agent architecture. In this architecture, an LLM is called repeatedly in a while-loop. At each step the agent decides which tools to call, and what the inputs to those tools should be. Those tools are then executed, and the outputs are fed back into the LLM as observations. The while-loop terminates when the agent decides it is not worth calling any more tools.

One of the few high level, pre-built agents we have in LangGraph - you can use it with [`createReactAgent`](/langgraphjs/reference/functions/langgraph_prebuilt.createReactAgent.html)

This is named after and based on the [ReAct](https://arxiv.org/abs/2210.03629) paper. However, there are several differences between this paper and our implementation:

- First, we use [tool-calling](#tool-calling) to have LLMs call tools, whereas the paper used prompting + parsing of raw output. This is because tool calling did not exist when the paper was written, but is generally better and more reliable.
- Second, we use messages to prompt the LLM, whereas the paper used string formatting. This is because at the time of writing, LLMs didn't even expose a message-based interface, whereas now that's the only interface they expose.
- Third, the paper required all inputs to the tools to be a single string. This was largely due to LLMs not being super capable at the time, and only really being able to generate a single input. Our implementation allows for using tools that require multiple inputs.
- Forth, the paper only looks at calling a single tool at the time, largely due to limitations in LLMs performance at the time. Our implementation allows for calling multiple tools at a time.
- Finally, the paper asked the LLM to explicitly generate a "Thought" step before deciding which tools to call. This is the "Reasoning" part of "ReAct". Our implementation does not do this by default, largely because LLMs have gotten much better and that is not as necessary. Of course, if you wish to prompt it do so, you certainly can.

See [this guide](../how-tos/time-travel.ipynb) for a full walkthrough of how to use the prebuilt ReAct agent.
11 changes: 11 additions & 0 deletions core-jdk8/src/site/markdown/concepts/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# FAQ

Common questions and their answers!

## The Compiled Graph Is thread safe?

Yes. the Compiled Graph is thread safe. It work on a new (and not shared) copy of state for each execution.

## Is the Compiled Graph + Checkpoints + MemorySaver thread safe ?

Yes. But the state consistency between parallel calls to `CompiledGraph.updateState()` is up to you.
53 changes: 53 additions & 0 deletions core-jdk8/src/site/markdown/concepts/high_level.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# LangGraph for Agentic Applications

## What does it mean to be agentic?

Other people may talk about a system being an "agent" - we prefer to talk about systems being "agentic". But what does this actually mean?

When we talk about systems being "agentic", we are talking about systems that use an LLM to decide the control flow of an application. There are different levels that an LLM can be used to decide the control flow, and this spectrum of "agentic" makes more sense to us than defining an arbitrary cutoff for what is or isn't an agent.

Examples of using an LLM to decide the control of an application:

- Using an LLM to route between two potential paths
- Using an LLM to decide which of many tools to call
- Using an LLM to decide whether the generated answer is sufficient or more work is need

The more times these types of decisions are made inside an application, the more agentic it is.
If these decisions are being made in a loop, then its even more agentic!

There are other concepts often associated with being agentic, but we would argue these are a by-product of the above definition:

- [Tool calling](agentic_concepts.md#tool-calling): this is often how LLMs make decisions
- Action taking: often times, the LLMs' outputs are used as the input to an action
- [Memory](agentic_concepts.md#memory): reliable systems need to have knowledge of things that occurred
- [Planning](agentic_concepts.md#planning): planning steps (either explicit or implicit) are useful for ensuring that the LLM, when making decisions, makes them in the highest fidelity way.

## Why LangGraph?

LangGraph has several core principles that we believe make it the most suitable framework for building agentic applications:

- [Controllability](../how-tos/index.md#controllability)
- [Human-in-the-Loop](../how-tos/index.md#human-in-the-loop)
- [Streaming First](../how-tos/index.md#streaming)

**Controllability**

LangGraph is extremely low level. This gives you a high degree of control over what the system you are building actually does. We believe this is important because it is still hard to get agentic systems to work reliably, and we've seen that the more control you exercise over them, the more likely it is that they will "work".

**Human-in-the-Loop**

LangGraph comes with a built-in persistence layer as a first-class concept. This enables several different human-in-the-loop interaction patterns. We believe that "Human-Agent Interaction" patterns will be the new "Human-Computer Interaction", and have built LangGraph with built in persistence to enable this.

**Streaming First**

LangGraph comes with first class support for streaming. Agentic applications often take a while to run, and so giving the user some idea of what is happening is important, and streaming is a great way to do that. LangGraph supports streaming of both events ([like a tool call being taken](../how-tos/stream-updates.ipynb)) as well as of tokens that an LLM may emit.

## Deployment

So you've built your LangGraph object - now what?

Now you need to deploy it.
There are many ways to deploy LangGraph objects, and the right solution depends on your needs and use case.
We're working on adding JavaScript/TypeScript support for LangGraph cloud, but in the meantime, here are some options:

- Use [Express.js](https://expressjs.com/) to stand up a server. You can then call this graph from inside the Express.js server as you see fit.
64 changes: 64 additions & 0 deletions core-jdk8/src/site/markdown/concepts/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Conceptual Guides

In this guide we will explore the concepts behind build agentic and multi-agent systems with LangGraph. We assume you have already learned the basics and want to deepen your understanding of LangGraph4j's underlying design and inner workings.

There are three main parts to this concept guide. First, we'll discuss at a very high level what it means to be agentic. Next, we'll look at lower-level concepts in LangGraph4j that are core for understanding how to build your own agentic systems. Finally, we'll discuss common agentic patterns and how you can achieve those with LangGraph4j. These will be mostly conceptual guides - for more technical, hands-on guides see our [how-to guides](../how-tos/index.md)

<!--
LangGraph4j for Agentic Applications
- [What does it mean to be agentic?](high_level.md#what-does-it-mean-to-be-agentic)
- [Why LangGraph4j](high_level.md#why-langgraph)
- [Deployment](high_level.md#deployment)
-->

Low Level Concepts

- [Graphs](low_level.md#graphs)
- [StateGraph](low_level.md#stategraph)
- [MessageGraph](low_level.md#messagegraph)
- [Compiling Your Graph](low_level.md#compiling-your-graph)
- [State](low_level.md#state)
- [Schema](low_level.md#schema)
- [Reducers](low_level.md#reducers)
- [MessageState](low_level.md#messagestate)
- [Nodes](low_level.md#nodes)
- [`START` node](low_level.md#start-node)
- [`END` node](low_level.md#end-node)
- [Edges](low_level.md#edges)
- [Normal Edges](low_level.md#normal-edges)
- [Conditional Edges](low_level.md#conditional-edges)
- [Entry Point](low_level.md#entry-point)
- [Conditional Entry Point](low_level.md#conditional-entry-point)
- [Checkpointer](low_level.md#checkpointer)
- [Threads](low_level.md#threads)
- [Checkpointer states](low_level.md#checkpointer-state)
- [Get state](low_level.md#get-state)
- [Get state history](low_level.md#get-state-history)
- [Update state](low_level.md#update-state)
- [Configuration](low_level.md#configuration)
- [Visualization](low_level.md#visualization)
- [Streaming](low_level.md#streaming)

<!--
Common Agentic Patterns
- [Structured output](agentic_concepts.md#structured-output)
- [Tool calling](agentic_concepts.md#tool-calling)
- [Memory](agentic_concepts.md#memory)
- [Human in the loop](agentic_concepts.md#human-in-the-loop)
- [Approval](agentic_concepts.md#approval)
- [Wait for input](agentic_concepts.md#wait-for-input)
- [Edit agent actions](agentic_concepts.md#edit-agent-actions)
- [Time travel](agentic_concepts.md#time-travel)
- [Multi-agent](agentic_concepts.md#multi-agent)
- [Planning](agentic_concepts.md#planning)
- [Reflection](agentic_concepts.md#reflection)
- [Off-the-shelf ReAct Agent](agentic_concepts.md#react-agent)
-->

***

## References

* [Langgraph.js Conceptual Guides](https://langchain-ai.github.io/langgraphjs/concepts/)
Loading

0 comments on commit 33ba752

Please sign in to comment.