DEV Community

Cover image for AI Agents - Workflows and Human In The Loop(HITL)
Ramya Perumal
Ramya Perumal

Posted on

AI Agents - Workflows and Human In The Loop(HITL)

LCEL - LangChain Common Expression Language

LCEL isn't specifically about using an Agent. LCEL is a way to compose LangChain components/Runnables into workflows.

In Python, everything is an object. Similarly, in LangChain, many components are implemented as Runnables, which means they can be executed and composed together.

LLM can be Runnable, or Prompt can be Runnable, or the output of the LLM can be Runnable.

Here, JSON data called "Topic" will be passed to the Prompt function that converts the JSON into messages, which will be passed to the LLM to convert the messages into AI messages, which will be passed to the parser to convert into a string. We will get the output as a string.

This line is called an assembly line or pipeline line. Runnable is not only able to take input, but also modify something and return the output.

The symbol for the pipeline is "|".

We can transform a normal function into a Runnable by using Runnable Lambda.

Runnable can have .invoke(), .batch(), .stream(), .ainvoke(), .abatch(), and .astream().

There are 2 types of workflows based on this Runnable.

1. Sequential Workflow

Follow one after another, which means Task A should be completed before Task B. So, it is a sequential order.

Topic -> Outline LLM -> Draft LLM -> Polish LLM -> Final

Two ways of calling Sequential Workflow:

# Way 1 — pipe operator (most common)
recipe_chain = prompt | model | parser

# Way 2 — explicit class (exactly the same)
recipe_chain_explicit = RunnableSequence(prompt, model, parser)
Enter fullscreen mode Exit fullscreen mode

2. Parallel Workflow

Here, independent tasks will run together, and the time to finish all the tasks will be the time that the slowest task takes.

Two ways of calling Parallel Workflow:

# Way 1 — explicit class
review = RunnableParallel(pros=pros, cons=cons, verdict=verdict)

# Way 2 — a plain dict inside a chain is auto-converted to RunnableParallel
summary_chain = (
    {"pros": pros, "cons": cons, "verdict": verdict}
    | p("Write a 4-line summary.\nPros:{pros}\nCons:{cons}\nVerdict:{verdict}")
    | model
    | parser
)
Enter fullscreen mode Exit fullscreen mode

Human in the Loop

A human will be involved in taking the final decision in an Agent operation. Risky operations will be sent for human approval.

Why do we need human approval? Some operations may be risky. If the Agent takes a decision without human approval, it might create side effects.

3 levels are available.

Level 1 - Approval Gateway Inside the Chain

query -> LLM -> output -> tool suggestion -> user approval -> result

Here, if the user approves, the action will be executed; otherwise, nothing will happen.

In the pipeline, if one of the parts is not executed, it will not proceed to the next part.

Here, every decision, even for a non-risky one, relies on human approval.

Level 2 - Review Tool Call by Hand

Every tool call suggested by the LLM will be reviewed by a human. Based on the human's decision, the workflow can either execute the tool, reject the tool call, or modify the tool call before execution. The workflow state or message can then be updated with the human's decision.

Level 3 - Middleware to Pause/Resume the Flow

Here, we will insert the middleware to determine which condition needs approval or can be processed without approval.

A human can approve, reject, edit, or respond to the approval.

If the human approves, the tool will be executed.

If the human rejects, a message will be sent with the ToolMessage.

If the human edits, the arguments passed to the tool will be changed according to the human-edited value.

If the human responds, the string typed by the human will be used.

Top comments (0)