| name | langgraph-functional-api |
| description | LangGraph Functional API (Python) — build stateful agent workflows with @entrypoint and @task decorators. Imperative Python style with LangGraph persistence, streaming, HITL, and durable execution. Ideal for wrapping existing agents (CrewAI, AutoGen, Strands) or complex parallel task logic. |
LangGraph Functional API Skill
Expert assistance for the LangGraph Functional API: imperative, Python-native agent workflows using @entrypoint and @task decorators. Gets you LangGraph persistence, streaming, and human-in-the-loop with minimal boilerplate — especially useful for wrapping existing agents or frameworks.
When to choose Functional API over Graph API:
- You're wrapping an existing agent (CrewAI, AutoGen, Strands, etc.)
- Your workflow is naturally imperative (sequential Python logic with branches)
- You need parallel task execution without defining a graph topology
- You want to add persistence/streaming to an agent you didn't write in LangGraph
Full corpus: ../langgraph/references/llms-txt.md (5.4 MB) and ../../langchain-deepagents/references/llms-full.md (10 MB).
When to Use This Skill
Activate when:
- Writing @entrypoint workflows — defining the top-level entry to a LangGraph application
- Defining @task functions — wrapping individual operations with checkpointing and retries
- Running tasks in parallel — invoking multiple tasks concurrently and awaiting results
- Wrapping third-party agents — integrating CrewAI, AutoGen, Strands, or any framework
- Configuring durable execution — choosing
exit, async, or sync durability modes
- Using tasks inside Graph API nodes — mixing both APIs in one graph
- Handling RunControl / GraphDrained — controlling graph execution lifecycle programmatically
- Streaming from functional workflows — getting token-level or state-level streaming output
Quick Reference
Minimal @entrypoint + @task
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.func import entrypoint, task
@task
def fetch_data(query: str) -> str:
return call_api(query)
@task
def process_data(raw: str) -> str:
return transform(raw)
@entrypoint(checkpointer=InMemorySaver())
def my_workflow(inputs: dict) -> dict:
raw = fetch_data(inputs["query"]).result()
processed = process_data(raw).result()
return {"output": processed}
result = my_workflow.invoke(
{"query": "hello"},
config={"configurable": {"thread_id": "1"}},
)
Parallel task execution
from langgraph.func import entrypoint, task
@task
def search_web(query: str) -> str:
return web_search(query)
@task
def search_docs(query: str) -> str:
return doc_search(query)
@entrypoint(checkpointer=InMemorySaver())
def research_workflow(inputs: dict) -> dict:
web_future = search_web(inputs["query"])
docs_future = search_docs(inputs["query"])
web_result = web_future.result()
docs_result = docs_future.result()
return {"web": web_result, "docs": docs_result}
Task retry policy
from langgraph.func import entrypoint, task
from langgraph.types import RetryPolicy
@task(retry=RetryPolicy(max_attempts=3, backoff_factor=2.0))
def flaky_api_call(payload: dict) -> dict:
return requests.post(API_URL, json=payload).json()
@entrypoint(checkpointer=InMemorySaver())
def workflow(inputs: dict) -> dict:
result = flaky_api_call(inputs).result()
return {"result": result}
Durable execution modes
from langgraph.runtime import RunControl
control = RunControl(
durability="sync"
)
Human-in-the-loop interrupt in a task
from langgraph.types import interrupt, Command
from langgraph.func import entrypoint, task
@task
def get_approval(action: str) -> str:
return interrupt({"prompt": f"Approve: {action}?"})
@entrypoint(checkpointer=InMemorySaver())
def workflow(inputs: dict) -> dict:
decision = get_approval(inputs["action"]).result()
if decision == "yes":
return {"status": "approved"}
return {"status": "rejected"}
workflow.invoke(
Command(resume="yes"),
config={"configurable": {"thread_id": "1"}},
)
Wrap a third-party agent (Strands, CrewAI, AutoGen)
from langgraph.func import entrypoint
from langgraph.checkpoint.memory import InMemorySaver
from strands import Agent as StrandsAgent
from strands_tools import http_request
strands_agent = StrandsAgent(tools=[http_request])
@entrypoint(checkpointer=InMemorySaver())
def strands_workflow(inputs: dict) -> dict:
result = strands_agent(inputs["prompt"])
return {"output": str(result)}
Tasks inside Graph API nodes (mixing APIs)
from langgraph.graph import StateGraph, START
from langgraph.func import task
from langgraph.types import RetryPolicy
@task(retry=RetryPolicy(max_attempts=2))
def llm_call(prompt: str) -> str:
return llm.invoke(prompt)
def my_node(state: State) -> State:
result = llm_call(state["input"]).result()
return {"output": result}
graph = StateGraph(State)
graph.add_node("my_node", my_node)
Streaming from an @entrypoint
config = {"configurable": {"thread_id": "1"}}
for chunk in my_workflow.stream(inputs, config, stream_mode="updates"):
print(chunk)
for chunk in my_workflow.stream(inputs, config, stream_mode="messages"):
print(chunk)
Functional API Concepts
| Concept | Decorator/Type | Notes |
|---|
| Workflow entry | @entrypoint(checkpointer=...) | Top-level callable; required for persistence |
| Unit of work | @task | Individually checkpointed; retryable |
| Invoke | workflow.invoke(inputs, config) | Blocking call |
| Stream | workflow.stream(inputs, config, stream_mode=...) | Streaming call |
| Parallel | Launch multiple tasks, call .result() to collect | Like asyncio.gather |
| Retry | @task(retry=RetryPolicy(...)) | Per-task retry logic |
| Durability | RunControl(durability="sync|async|exit") | Checkpoint frequency |
| Interrupt | interrupt(payload) inside task | Pause for human input |
| Resume | workflow.invoke(Command(resume=value), config) | Continue after interrupt |
| Third-party | Any callable inside @entrypoint | Wrap CrewAI, AutoGen, etc. |
Functional API vs Graph API
| Need | Use |
|---|
| Explicit graph topology / visualization | Graph API |
| Imperative Python logic | Functional API |
| Wrapping an existing agent | Functional API |
| Named, inspectable stages | Graph API |
| Parallel tasks with dynamic count | Functional API |
| Complex conditional branching | Graph API |
| Minimal boilerplate | Functional API |
Fan-out with Send | Graph API |
Reference Files
| File | Location |
|---|
| LangGraph Python docs index | ../langgraph/references/llms.md |
| 1473-page corpus summaries | ../langgraph/references/llms-txt.md |
| Full content + all code | ../../langchain-deepagents/references/llms-full.md |
Key doc pages: docs.langchain.com/oss/python/langgraph/functional-api, /use-functional-api, /choosing-apis, /durable-execution