HumanNode
nae.HumanNode ¶
HumanNode(name: Optional[str] = None, node_prompt: str = 'Please review the following message and provide feedback.', n: int = 1, show: Optional[Union[str, Callable]] = None, into: str = 'messages', cache_ttl: Optional[int] = None, retry: bool = False)
Bases: Node
Resumable human-in-the-loop step, backed by LangGraph's interrupt().
When the run reaches a HumanNode it pauses and surfaces a payload for a
person to review (by default the content of a recent message, chosen by
n; override with show). The run resumes when you invoke again with
Command(resume=value) on the same thread_id; the resume value lands
into a state key — "messages" (default) wraps it as a HumanMessage
and appends it, any other key writes the raw value (so a router can gate on
the answer). Resume requires the graph to be built with a checkpointer.
Examples:
from nae import AgentNode, HumanNode, AgenticGraph
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import Command
draft = AgentNode(llm=llm, node_prompt="Draft a reply.")
review = HumanNode(node_prompt="Approve or edit this draft:", n=1)
finalize = AgentNode(llm=llm, node_prompt="Incorporate the human feedback.")
draft > review > finalize
graph = AgenticGraph(start_node=draft, end_nodes={finalize},
checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "demo-1"}}
graph.invoke("Reply to the customer.", config=config) # pauses at review
graph.invoke(Command(resume="Looks good, ship it."), config=config)
Initialize a HumanNode — free-form human-in-the-loop via interrupt/resume.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Optional[str]
|
Unique identifier for the node. |
None
|
node_prompt
|
str
|
key under which |
'Please review the following message and provide feedback.'
|
n
|
int
|
which prior message to surface for review when |
1
|
show
|
Optional[Union[str, Callable]]
|
what to surface for review — None => the n-th message's content (default behavior); a str => that literal; a callable => show(state). |
None
|
into
|
str
|
where the human's free-form resume value lands — "messages" (default) wraps it as a HumanMessage and appends; any other key writes the raw value to that key (for a router to gate on). |
'messages'
|
cache_ttl
|
Optional[int]
|
see Node — node-level result caching. |
None
|
retry
|
bool
|
see Node — node-level retry on exception. |
False
|
__call__ ¶
Pause the run for human input and return the reply as a delta.
Computes the display payload — show(state) / the literal show / the
n-th message's content (nothing when n <= 0 or too few messages) —
then calls LangGraph's interrupt() with {node_prompt: display}. On
the FIRST pass this raises the interrupt and suspends the run; when
resumed via Command(resume=value), interrupt() returns that value,
which is written into the target key ("messages" wraps it as a
HumanMessage, otherwise the raw value is written).
Raises:
| Type | Description |
|---|---|
ValueError
|
If |