LangChain LangGraph
Module 1 Module 2 Module 3 Module 4 Module 5 Module 6
Module 6 · Production
1 6-1 Creating
2 6-2 Connecting
3 6-3 Double Texting
4 6-4 Assistant
HomeLangGraphModule 6 · Production6-4 Assistant
📓 Notebook 📖 Explained
LANGGRAPH MODULE 6 · LESSON 4

Assistants

Quickly create, version and manage Assistants through LangGraph SDK - an in-depth explanation of how to use the same graph and different configurable parameters to create multiple sets of isolated business assistants.

1What are Assistants and their core values

AssistantIt is a concept provided by LangGraph Platform: it binds "Graph" and "Configuration" together, persists them in PostgreSQL, and allocates a uniqueassistant_id

One sentence to understand:The same picture + different config = different Assistant

core scene

The task_mAIstro application uses the same picture and passes differenttodo_category("personal" / "work") andtask_maistro_roleCreate two independent ToDo assistants without interfering with each other.

2Prerequisite: Configuration design of the graph

Assistants are defined internally in the dependency graphconfigurable field. task_mAIstro picture inconfiguration.pyThree configurable fields are declared in and read within the node:

# configuration.py(简化)
from dataclasses import dataclass, field
from langgraph.config import get_configurable

@dataclass
class Configuration:
    user_id: str = "default_user"
    todo_category: str = "general"      # "personal" | "work" | ...
    task_maistro_role: str = ""          # 系统提示词中的角色说明

# 在图节点内读取
config = Configuration(**get_configurable())
design principles

The diagram itself does not solidify the business logic, but passesconfigurableFields receive runtime parameters. This allows the same code to produce completely different behavior in different Assistant instances.

3Create Assistant (create)

useclient.assistants.create()Create an Assistant, passing in the graph name and initial configuration.

from langgraph_sdk import get_client

client = get_client(url="http://localhost:8123")

# 创建 personal 助手(version 1)
personal_assistant = await client.assistants.create(
    "task_maistro",   # 已部署的图名称
    config={"configurable": {"todo_category": "personal"}}
)
print(personal_assistant["assistant_id"])   # uuid
print(personal_assistant["version"])         # 1

create()The returned object containsassistant_idversionconfigand persist to PostgreSQL.

Note

When deploying the diagram, aDefault Assistant(version 1, empty config). If used directlyclient.runs.stream(thread_id, "task_maistro", ...)Instead of passing it onassistant_id, this default Assistant is used.

4Versioned update assistant (update)

useclient.assistants.update()Add new configuration to existing Assistant, each call will generate anew version, the old version is automatically retained.

Version 1
todo_category: "personal"
Version 2 (after update)
+ user_id: "lance"
+ task_maistro_role: "..."
task_maistro_role = """You are a friendly and organized personal task assistant.

- When providing a 'todo summary':
  1. List tasks grouped by deadline (overdue, today, this week, future)
  2. Highlight tasks missing deadlines
- Proactively ask for deadlines when new tasks lack them
- Tone: encouraging and supportive"""

configurations = {
    "todo_category": "personal",
    "user_id": "lance",
    "task_maistro_role": task_maistro_role,
}

personal_assistant = await client.assistants.update(
    personal_assistant["assistant_id"],   # 传入已有 ID
    config={"configurable": configurations}
)
print(personal_assistant["version"])  # 2
The value of versioning

every timeupdate()The old version will not be overwritten, but the new version will be appended. This provides a safety net for experimental configurations - if newtask_maistro_roleIf the effect is not ideal, you can switch back to the historical version at any time.

5Practical combat: Personal and Work assistants

Typical use case of task_mAIstro: Use two Assistants to manage personal tasks and work tasks respectively, isolated from each other.

Personal Assistant

Personal task assistant

todo_category: "personal"
Use an encouraging tone, remind you of deadlines, and focus on life matters (swimming lessons, housework, travel, etc.).

Work Assistant

Work task assistant

todo_category: "work"
Professional and efficient, recommending reasonable deadlines based on task types (DevRel 1 day, Document Sprint 3 days, etc.).

Work Assistant example: Enforcing deadlines

user_input = "Create another ToDo: Finalize set of report generation tutorials."
thread = await client.threads.create()

async for chunk in client.runs.stream(
    thread["thread_id"],
    work_assistant_id,   # 使用 work assistant 的 ID
    input={"messages": [HumanMessage(content=user_input)]},
    stream_mode="values"
):
    if chunk.event == 'values':
        convert_to_messages(chunk.data["messages"])[-1].pretty_print()
Work assistant replies (ask proactively when there is no deadline)

Human: Create another ToDo: Finalize set of report generation tutorials.
AI: I notice "Finalize set of report generation tutorials" doesn't have a deadline yet. Based on similar documentation tasks, this might take around 3 days. Would you like to set a deadline with this in mind?
# 用户在同一线程回复截止日期
user_input = "OK, for this task let's get it done by next Tuesday."
async for chunk in client.runs.stream(
    thread["thread_id"],   # 复用同一线程,保持上下文
    work_assistant_id,
    input={"messages": [HumanMessage(content=user_input)]},
    stream_mode="values"
):
    if chunk.event == 'values':
        convert_to_messages(chunk.data["messages"])[-1].pretty_print()
AI: I've added "Finalize set of report generation tutorials" to your work ToDo list with a deadline of next Tuesday.

Personal Assistant Example: Encouraging ToDo Summary

user_input = "Give me a todo summary."
thread = await client.threads.create()
async for chunk in client.runs.stream(
    thread["thread_id"],
    personal_assistant_id,   # 切换到 personal assistant
    input={"messages": [HumanMessage(content=user_input)]},
    stream_mode="values"
):
    if chunk.event == 'values':
        convert_to_messages(chunk.data["messages"])[-1].pretty_print()
AI: Here's your personal ToDo summary:

📅 This Weekend
• Check on swim lessons for the baby

🔜 Future
• Check AmEx points for winter travel (no deadline set yet)

I notice "Check AmEx points" doesn't have a deadline. Would you like to add one so we can track it better?
Key point: natural isolation of data

The two Assistants, Personal and Work, each use differenttodo_category, so the keys when writing to Store are different, and their respective ToDo lists are completely independent and will not contaminate each other.

6Search and Manage Assistants

All Assistants are persisted in PostgreSQL and can be queried and deleted at any time through the SDK.

Search all Assistants

assistants = await client.assistants.search()
for assistant in assistants:
    print({
        'assistant_id': assistant['assistant_id'],
        'version': assistant['version'],
        'config': assistant['config']
    })
Search results (example)

{'assistant_id': 'abc-111', 'version': 1, 'config': {'configurable': {'todo_category': 'work', ...}}}
{'assistant_id': 'abc-222', 'version': 2, 'config': {'configurable': {'todo_category': 'personal', ...}}}
{'assistant_id': 'abc-000', 'version': 1, 'config': {}} ← Default assistant automatically created on deployment

Delete Assistant

# 先创建一个临时 assistant
temp_assistant = await client.assistants.create(
    "task_maistro",
    config={"configurable": configurations}
)

# 删除它
await client.assistants.delete(temp_assistant["assistant_id"])

# 确认已删除
assistants = await client.assistants.search()
print(len(assistants))  # 回到删除前的数量
Impact of deletion

Deleting an Assistant will not delete the thread (Thread) and session history associated with it. Threads are stored independently. But after deletingassistant_idInvalid and can no longer be used to create new runs.

Get assistant_id through search

# 按返回顺序分配(通常按创建时间倒序)
work_assistant_id     = assistants[0]['assistant_id']
personal_assistant_id = assistants[1]['assistant_id']

In a production environment, it is recommended toassistant_idPersistence to the application database instead of retrieving fromsearch()Inferred indexing - ordering may be unstable when multiple people are collaborating.

7Architecture summary and applicable scenarios

DimensionsDefault AssistantCustom Assistant
How to create Automatically generated when deploying diagrams client.assistants.create()
Configuration Empty config (use graph defaults) Custom configurable fields
Versioning Fixed version 1 every timeupdate()incremental version
data isolation All calls share a context Isolate data by different config keys
Applicable scenarios Development testing, single scenario Multiple users, multiple business lines, multiple languages, etc.
When to use Assistants

when you needThe same set of graph logic serves multiple configurationsUse Assistants when using: multi-tenant SaaS (independent configuration for each customer), separation of roles (customer service vs sales vs technical), A/B testing different system prompts, multi-language assistants (Chinese version vs English version). Assistants eliminate the need to re-deploy code for these scenarios.

Module 6 Full Link Review

6-1 Creating: Package the graph code into a Docker image, and use docker-compose to start three services (LangGraph Server + PostgreSQL + Redis).
6-2 Connecting: Connect to services through LangGraph SDK, manage threads and operations, and achieve streaming output.
6-3 Double Texting:usemultitask_strategyHandle concurrent messages - Reject / Enqueue / Interrupt / Rollback.
6-4 Assistants: Use the same picture, differentconfigurableCreate multiple sets of isolation assistants to support version management.