Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosLinus Tech Tips: I Thought These Guys Made Cables(21.09.2026 um 19:15 Uhr)
Sicherheitslücken (CVE)GitHub Actions leaking secrets when Miri output is cached(21.09.2026 um 02:00 Uhr)
Sichere ProgrammierungBuilding a Polymarket TWAP Momentum Reversal Detector(21.09.2026 um 20:02 Uhr)
Sichere ProgrammierungWhy Does RAG Miss Information That's Clearly in the Document?(21.09.2026 um 20:04 Uhr)
YouTube Security VideosLinus Tech Tips: I Thought These Guys Made Cables(21.09.2026 um 19:15 Uhr)
Sicherheitslücken (CVE)GitHub Actions leaking secrets when Miri output is cached(21.09.2026 um 02:00 Uhr)
Sichere ProgrammierungBuilding a Polymarket TWAP Momentum Reversal Detector(21.09.2026 um 20:02 Uhr)
Sichere ProgrammierungWhy Does RAG Miss Information That's Clearly in the Document?(21.09.2026 um 20:04 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Understanding FilesystemBackend in LangChain's Deep Agents

In a previous example, we used StateBackend, where files belonged to a specific LangGraph conversation thread. This time, we are using something different: FilesystemBackend lets a Deep Agent read and write real files on your…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

In a previous example, we used StateBackend, where files belonged to a specific LangGraph conversation thread.



This time, we are using something different:




FilesystemBackend lets a Deep Agent read and write real files on your machine.




That means if the agent creates a Markdown file, Python file, or project folder, it remains on your disk even after the script finishes.



This is useful for local coding assistants, document-generation tools, and development workflows. But because the agent can modify real files, it must be used carefully.









What This Example Demonstrates



The code shows four important behaviors:




  1. The agent writes files to a real folder on disk.

  2. Those files remain after the Python program stops.


  3. thread_id does not isolate files when using local disk storage.


  4. CompositeBackend can keep temporary agent artifacts separate from your real project files.



Here is the high-level comparison:




StateBackend
────────────
Thread A → temporary files for Thread A
Thread B → separate temporary files for Thread B

FilesystemBackend
─────────────────
Thread A ─┐
├── same real folder on your computer
Thread B ─┘






With FilesystemBackend, files are not stored inside LangGraph state. They are regular operating-system files under a configured directory. (docs.langchain.com)









The Full Example






"""
Demonstrates Deep Agents
' FilesystemBackend (real files on disk).

What you will observe:
1. The agent writes real files to disk under a root_dir.
2. Files persist after the Python process ends — inspect them.
3. Thread isolation does NOT apply (files are real OS files).
4. CompositeBackend keeps internal agent artifacts out of your project.
"""

from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, FilesystemBackend, StateBackend
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv

load_dotenv()

model = init_chat_model(
"openrouter:nvidia/nemotron-3-super-120b-a12b",
max_tokens=4096,
)


# ---------------------------------------------------------
# 1. FilesystemBackend (standalone) — writes under a root_dir
# ---------------------------------------------------------
# Files go to real disk under ./agent_workspace/ on your machine.
agent = create_deep_agent(
model=model,
backend=FilesystemBackend(
root_dir="./agent_workspace",
virtual_mode=True,
),
)


def run(thread_id: str, prompt: str):
result = agent.invoke(
{"messages": [{"role": "user", "content": prompt}]},
config={"configurable": {"thread_id": thread_id}},
)
print("\n" + "=" * 70)
print(f"THREAD: {thread_id}")
print("=" * 70)
print(result["messages"][-1].content)


# ---------------------------------------------------------
# Turn 1 — write a real file
# ---------------------------------------------------------
run(
"demo-thread-1",
"""
Use the write_file tool to create a file:

Path: /notes/todo.md

Content:
# To-do
- Buy groceries
- Finish the project
- Review pull requests

After writing:
1. Use ls to confirm it exists.
2. Tell me the absolute OS path where this file was written.
""",
)


# ---------------------------------------------------------
# Turn 2 — same thread reads it back
# ---------------------------------------------------------
run(
"demo-thread-1",
"""
Use read_file to read /notes/todo.md.
Then list the three to-do items.
""",
)


# ---------------------------------------------------------
# Turn 3 — different thread ALSO sees the file
# ---------------------------------------------------------
# Unlike StateBackend, files are real OS files — they are NOT
# isolated by thread_id. Any thread can read any file.
run(
"demo-thread-2",
"""
Use ls to inspect the filesystem.
Can you find /notes/todo.md? Read it and report its contents.
""",
)

print("\n" + "=" * 70)
print("Files written to: ./agent_workspace/ -- check with:")
print(" dir agent_workspace\\notes\\")
print(" type agent_workspace\\notes\\todo.md")
print("=" * 70)


# ---------------------------------------------------------
# 2. CompositeBackend (recommended for real projects)
# ---------------------------------------------------------
# Internal agent artifacts (large tool results, conversation
# history) go to ephemeral StateBackend. Only files under
# /workspace/ hit real disk.
print("\n" + "=" * 70)
print("COMPOSITE BACKEND (recommended pattern)")
print("=" * 70)

agent2 = create_deep_agent(
model=model,
backend=CompositeBackend(
default=StateBackend(),
routes={
"/workspace/": FilesystemBackend(
root_dir="./my_project",
virtual_mode=True,
),
},
),
)

result = agent2.invoke(
{
"messages": [
{
"role": "user",
"content": (
"Write a file at path /workspace/src/hello.py "
"with content: print('hello from FilesystemBackend'). "
"Then confirm it exists via ls."
),
}
]
},
config={"configurable": {"thread_id": "composite-demo"}},
)
print(result["messages"][-1].content)
print("\nFile written to: ./my_project/src/hello.py")












Before You Run the Code



Install the required packages:




pip install deepagents langchain langgraph python-dotenv






You also need your model provider credentials configured. Since this example uses OpenRouter, place your API key in a .env file:




OPENROUTER_API_KEY=your_api_key_here






The call to load_dotenv() loads environment variables from that file:




from dotenv import load_dotenv

load_dotenv()






Do not commit .env files containing real API keys to GitHub.









The Important Difference: Real Disk vs Agent State



Before studying the code, understand this difference.











































Feature StateBackend FilesystemBackend
Where files live LangGraph state Your computer’s filesystem
Survives script restart No, with InMemorySaver
Yes
Isolated by thread_id
Yes No
Good for Temporary agent artifacts Local projects and durable output
Risk level Lower Higher
Can affect real project files No Yes


FilesystemBackend reads and writes directly to the local filesystem. It is intended for controlled local development or carefully configured CI/CD workflows—not directly exposed web applications or multi-user APIs. (reference.langchain.com)









Step 1: Creating the Model






model = init_chat_model(
"openrouter:nvidia/nemotron-3-super-120b-a12b",
max_tokens=4096,
)






This creates the language model used by the Deep Agent.



The max_tokens=4096 argument limits the size of generated responses. This is practical when using paid APIs because it helps control token usage and cost.



You can use another supported model later. The storage behavior explained in this article comes from the backend configuration, not from the model itself.









Step 2: Creating a FilesystemBackend



Here is the most important part of the first agent:




agent = create_deep_agent(
model=model,
backend=FilesystemBackend(
root_dir="./agent_workspace",
virtual_mode=True,
),
)






This tells the agent:




Use the agent_workspace folder as the location for real file operations.




When the agent receives this virtual path:




/notes/todo.md






it maps to a real path similar to this:




your-project-folder/
└── agent_workspace/
└── notes/
└── todo.md






The exact full path depends on where you run your Python script.



For example, if your project is located at:




C:\Users\Talha\deep-agents-demo






the final file could be:




C:\Users\Talha\deep-agents-demo\agent_workspace\notes\todo.md






On macOS or Linux, it could look like:




/home/talha/deep-agents-demo/agent_workspace/notes/todo.md












Why Use virtual_mode=True?






virtual_mode=True






This is an important safety setting.



It lets the agent use clean virtual paths such as:




/notes/todo.md






while mapping them underneath the configured root_dir.



It also blocks common path-escape attempts such as:




../../some-other-folder/file.txt






or:




~/secret-file.txt






However, this is not full sandboxing. It provides path-based restrictions, but it does not isolate the Python process like a container or remote sandbox would. The official Deep Agents documentation recommends using virtual_mode=True together with a configured root directory. (reference.langchain.com)









A Small Improvement: Use an Absolute root_dir



For beginner projects, this works:




root_dir="./agent_workspace"






But using an absolute path makes your code more predictable, especially if you run the script from different directories.



Here is a slightly safer version:




from pathlib import Path

workspace_dir = Path("./agent_workspace").resolve()

agent = create_deep_agent(
model=model,
backend=FilesystemBackend(
root_dir=workspace_dir,
virtual_mode=True,
),
)






Now workspace_dir becomes a complete OS path automatically.



For example:




C:\Users\Talha\deep-agents-demo\agent_workspace






or:




/home/talha/deep-agents-demo/agent_workspace












Step 3: The run() Helper Function



The helper function invokes the agent:




def run(thread_id: str, prompt: str):
result = agent.invoke(
{"messages": [{"role": "user", "content": prompt}]},
config={"configurable": {"thread_id": thread_id}},
)






The thread_id is still passed to LangGraph:




config={"configurable": {"thread_id": thread_id}}






But with FilesystemBackend, the file itself does not belong to the thread.



This is a crucial distinction:




thread_id controls conversation/checkpoint state
root_dir controls real file location






The thread can affect conversation memory, but a file written to disk is visible to anything that has permission to access that disk location.









Turn 1: Writing a Real Markdown File



The first prompt asks the agent to create:




/notes/todo.md






with this content:




# To-do
- Buy groceries
- Finish the project
- Review pull requests






Because the backend root directory is:




./agent_workspace






the actual file becomes:




./agent_workspace/notes/todo.md






The agent should then call ls to confirm that the file exists.



Conceptually, the filesystem now looks like this:




agent_workspace/
└── notes/
└── todo.md






Unlike StateBackend, this file is not temporary agent state. It is a real file created on your computer.









Turn 2: Reading the File Again



The second call uses the same thread:




run(
"demo-thread-1",
...
)






The agent reads:




/notes/todo.md






and should report:




  1. Buy groceries

  2. Finish the project

  3. Review pull requests



At this point, it may look similar to the StateBackend example. But the reason the file is available is different.



With StateBackend, the same thread ID matters because files are stored in thread state.



With FilesystemBackend, the file is available because it physically exists in:




./agent_workspace/notes/todo.md






The agent could read it even after restarting the Python script, as long as the file is still on disk.









Turn 3: A Different Thread Can Read the Same File



Now notice this call:




run(
"demo-thread-2",
...
)






The code uses a different thread ID:




demo-thread-2






But the agent can still find and read:




/notes/todo.md






Why?



Because both threads point to the same real directory:




./agent_workspace






Here is the flow:




Thread: demo-thread-1

│ writes

agent_workspace/notes/todo.md

│ reads

Thread: demo-thread-2






This means thread_id is not a filesystem security boundary when using FilesystemBackend.




If two agents use the same FilesystemBackend root directory, they can access the same files—subject to operating-system permissions and the backend configuration.










Verifying the File Yourself



Your code prints these Windows commands:




dir agent_workspace\notes\
type agent_workspace\notes\todo.md






Run them in Command Prompt:




dir agent_workspace\notes\
type agent_workspace\notes\todo.md






Expected output:




# To-do
- Buy groceries
- Finish the project
- Review pull requests






For PowerShell, you can use:




Get-ChildItem .\agent_workspace\notes\
Get-Content .\agent_workspace\notes\todo.md






For macOS or Linux:




ls agent_workspace/notes/
cat agent_workspace/notes/todo.md






This is a helpful test because it proves that the file exists independently of the agent and the Python process.









Why CompositeBackend Is Better for Real Projects



The second part of the code introduces this:




CompositeBackend(
default=StateBackend(),
routes={
"/workspace/": FilesystemBackend(
root_dir="./my_project",
virtual_mode=True,
),
},
)






This is a hybrid approach.



It says:




  • Use StateBackend for most agent files.

  • Use real disk only for paths beginning with /workspace/.



Here is the routing idea:




Agent path                         Backend used
────────────────────────────────────────────────────
/workspace/src/hello.py FilesystemBackend
/tmp/tool-output.txt StateBackend
/internal/agent-notes.md StateBackend






And visually:




                         CompositeBackend

┌──────────────┴──────────────┐
│ │
/workspace/... paths All other paths
│ │
▼ ▼
FilesystemBackend StateBackend
./my_project/ temporary state






CompositeBackend routes file operations by path prefix. A matching route sends the operation to that backend; paths that do not match a route use the default backend. (reference.langchain.com)









Understanding the /workspace/ Route



This configuration:




routes={
"/workspace/": FilesystemBackend(
root_dir="./my_project",
virtual_mode=True,
),
},






means that this agent path:




/workspace/src/hello.py






will become a real file at:




./my_project/src/hello.py






The agent prompt says:




"Write a file at path /workspace/src/hello.py "
"with content: print('hello from FilesystemBackend'). "
"Then confirm it exists via ls."






After the agent finishes, your project folder should contain:




my_project/
└── src/
└── hello.py






The contents of hello.py should be:




print("hello from FilesystemBackend")












Why Keep Internal Files in StateBackend?



Deep Agents can create temporary artifacts while working, such as:




  • Large tool results

  • Intermediate research notes

  • Planning files

  • Conversation-related artifacts

  • Temporary generated content



You may not want these files to appear in your actual source-code project.



That is why this pattern is useful:




default=StateBackend()






Only explicit project output goes to disk:




/workspace/...






Everything else remains temporary and isolated in agent state.



This creates a cleaner project directory and reduces the chance that internal agent artifacts are mixed with your application files.









FilesystemBackend vs CompositeBackend











































Question Standalone FilesystemBackend
CompositeBackend
Where do files go? One real disk folder Different locations based on path
Are all agent files written to disk? Usually yes Only selected routes
Can temporary artifacts stay ephemeral? No, not by default Yes
Best for Small local experiments Real development workflows
Project-folder cleanliness Can become messy Easier to control
Configuration complexity Simple Slightly more advanced


For a quick experiment, use FilesystemBackend.



For a project where you want the agent to create real source files but keep its internal work temporary, use CompositeBackend.









Important Safety Warning



FilesystemBackend is powerful because it gives an AI agent access to real files.



That also makes it risky.



The official documentation warns that agents using this backend may be able to read accessible secrets such as .env files, API keys, or credentials, and that file changes are permanent. It is intended for controlled local development and carefully managed CI/CD environments—not public web servers, multi-tenant apps, or untrusted user input. (reference.langchain.com)






Avoid These Mistakes






1. Do not point the agent at your entire computer



Avoid this:




FilesystemBackend(
root_dir="C:/",
virtual_mode=True,
)






Or on macOS/Linux:




FilesystemBackend(
root_dir="/",
virtual_mode=True,
)






Instead, create a dedicated workspace:




FilesystemBackend(
root_dir="./agent_workspace",
virtual_mode=True,
)












2. Do not expose secrets inside the workspace



Avoid placing files like these inside the folder available to the agent:




.env
credentials.json
private_key.pem
config.production.json






A safer project structure might look like:




my-app/
├── .env # Keep outside agent workspace
├── app/
├── agent_workspace/ # Agent can access this
└── run_agent.py












3. Do not use it directly in a public API



If users can send prompts to an agent through a website, avoid giving that agent direct access to your host machine’s filesystem.



For production systems, prefer:





  • StateBackend for temporary per-thread files


  • StoreBackend for durable managed storage

  • A sandbox backend for isolated execution environments



Deep Agents specifically recommends safer state, store, or sandbox alternatives for web servers and HTTP APIs. (reference.langchain.com)









4. Do not treat thread_id as access control



This is unsafe thinking:




“My files are secure because each user has a different thread_id.”






That is true for StateBackend, but not for a shared FilesystemBackend.



If different users, agents, or processes share the same disk folder, they may see the same files.



Use proper authentication, authorization, per-user directories, and operating-system permissions in real applications.









A Recommended Project Structure



For experimenting safely, use a layout like this:




deepagents-filesystem-demo/

├── .env
├── filesystem_demo.py

├── agent_workspace/
│ └── notes/
│ └── todo.md

└── my_project/
└── src/
└── hello.py






You can also add these generated folders to .gitignore:




# Agent-generated workspace files
agent_workspace/

# Add this only if you do not want generated project files in Git
# my_project/

# Never commit environment secrets
.env












Final Takeaway



FilesystemBackend allows a Deep Agent to work with files that truly exist on your machine.



The core idea is:




StateBackend
→ files are temporary and tied to a LangGraph thread

FilesystemBackend
→ files are real, persistent, and shared through the operating system






For simple local experiments:




FilesystemBackend(
root_dir="./agent_workspace",
virtual_mode=True,
)






For more organized real-world projects:




CompositeBackend(
default=StateBackend(),
routes={
"/workspace/": FilesystemBackend(
root_dir="./my_project",
virtual_mode=True,
)
}
)






This hybrid approach gives you the best of both worlds:




  • real project files where you want them;

  • temporary agent artifacts kept out of your project folder.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Understanding FilesystemBackend in LangChain's Deep Agents

Thematisch verwandte Begriffe: Understanding, FilesystemBackend, LangChains, Deep · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-63416 | draw.io is a configurable diagramming and whiteboarding application. Pri…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick