An autonomous AI agent that analyzes CSV data, generates plots, and posts the results to Slack — all driven by a locally-hosted LLM. The agent is built on DeepAgents / LangGraph and runs its file and shell operations inside a sandboxed backend.
Given a natural-language instruction (e.g. "Analyze this CSV and generate a beautiful plot, then send the analysis to Slack"), the agent will:
- Read and reason about a CSV file living in the sandbox filesystem.
- Use its tools to generate a chart (via
pandas+matplotlib). - Send the resulting analysis and image to a Slack channel.
The model is instructed to only ever use the provided tools for external actions (no raw HTTP requests, no ad-hoc Slack calls).
| Layer | Technology |
|---|---|
| Agent framework | deepagents on top of LangGraph / LangChain |
| LLM | Local models served by Ollama via langchain-ollama (gemma4:e2b, llama3.1:8b) |
| Execution sandbox | LocalShellBackend (local shell) — with an optional Daytona cloud sandbox backend |
| Data / plotting | pandas, matplotlib |
| Messaging | Slack via slack_sdk |
| State / checkpoints | LangGraph InMemorySaver |
| Observability | LangSmith tracing (optional) |
| Config | python-dotenv |
data_analysisAgent/
├── agent.py # Main entry point — builds and runs the deep agent
├── tools.py # Agent tools: generate_plot() and slack_send_message()
├── sandbox.py # Sets up a Daytona cloud sandbox + seeds sample CSV
├── localShellSandbox.py # Seeds sample sales data into the local shell backend
├── ollama_test.py # Minimal smoke test for the local Ollama model
├── bin/
│ └── sales_data.csv # Sample dataset
├── requirements.txt
└── .env # Secrets & config (not committed)
agent.py— the runnable entry point. It creates aLocalShellBackend, points aChatOllamamodel at it, registers the Slack tool, and streams a single analysis task to completion. The system prompt constrains the agent to using the provided tools only.tools.py— the two tools the agent can call:_generate_plot(csv_path, output_path)— executes a pandas/matplotlib script inside the sandbox to produce a bar chart PNG._slack_send_message(text, file_path?)— posts a message to Slack, optionally uploading a file downloaded from the sandbox. UsesDEFAULT_CHANNELfor text andFILE_CHANNELfor file uploads.
- Backends — the agent runs shell/file operations through a backend.
LocalShellBackendruns them on your machine;sandbox.pyshows how to swap in aDaytonaSandboxfor isolated cloud execution.
- Python 3.11+
- Ollama installed and running, with the desired model pulled:
ollama pull gemma4:e2b # or llama3.1:8b - A Slack app / user token with permission to post messages and upload files.
- (Optional) A Daytona account if you want cloud-sandboxed execution.
-
Clone and enter the project
git clone <repo-url> cd data_analysisAgent
-
Create a virtual environment and install dependencies
python -m venv .venv source .venv/bin/activate pip install -r requirements.txt -
Create a
.envfile in the project root:# Slack SLACK_USER_TOKEN=xoxp-... # Daytona (optional — only needed for cloud sandbox) DAYTONA_API_KEY=... DAYTONA_SANDBOX_ID=... # LangSmith tracing (optional) LANGSMITH_API_KEY=... LANGSMITH_PROJECT=... LANGSMITH_TRACING=true LANGSMITH_ENDPOINT=https://api.smith.langchain.com
-
Configure Slack channels — update
DEFAULT_CHANNELandFILE_CHANNELintools.pyto your own channel IDs.
-
Seed sample data (writes
bin/sales_data.csvinto the local backend):python localShellSandbox.py
-
Run the agent:
python agent.py
The agent will analyze the CSV referenced in agent.py, generate a plot, and post the results to Slack. Progress is streamed to the terminal step by step.
To analyze your own data, edit the input_message in agent.py to point at a different CSV path and describe the task you want performed.
sandbox.py demonstrates connecting to a Daytona sandbox and uploading a sample dataset. To run the agent in the cloud instead of on your local shell, construct a DaytonaSandbox backend (as in sandbox.py) and pass it to create_deep_agent in place of the LocalShellBackend.
- Model — change the
model="gemma4:e2b"argument inagent.pyto any model available in your Ollama install.ollama_test.pyis a quick way to confirm a model responds. - Sandbox root —
LocalShellBackend(root_dir=".")scopes file operations to the project directory. - Paths — plot output defaults to
/home/daytona/plot.png(a Daytona path); when running locally, pass a localoutput_pathto the plot tool.
.envis git-ignored — never commit tokens.- The
LocalShellBackendexecutes agent-generated code on your machine. For untrusted inputs or stronger isolation, prefer the Daytona sandbox backend.
No license specified yet.