在这里插入图片描述

1. 前言(Demo 演示)

在日常工作中,数据分析往往需要反复编写 Python 代码、查阅文档、调试图表。如果能有一个智能助手,直接通过自然语言对话完成数据探索、统计分析和可视化,效率将大幅提升。

本文是一个 技术演示项目(Demo),旨在快速验证"自然语言驱动数据分析"的可行性,不适合直接用于生产环境。我们将从零搭建一个 数据分析智能助手,后端使用 LangChain Agent 驱动 LLM 自主生成并执行 Python 代码,前端使用 Streamlit 提供交互式聊天界面,LLM 选用 DeepSeek(OpenAI 兼容接口),成本低且效果出色。
本文将带你从零搭建一个 数据分析智能助手,后端使用 LangChain Agent 驱动 LLM 自主生成并执行 Python 代码,前端使用 Streamlit 提供交互式聊天界面,LLM 选用 DeepSeek(OpenAI 兼容接口),成本低且效果出色。

最终效果:上传一个 CSV 文件,然后像聊天一样提问——“帮我画一张销售额的月度趋势图”、“计算各品类的平均利润”——Agent 会自动生成代码、执行并返回结果。

2. 项目结构

project/
├── .env              # 存放 API Key
├── agent.py          # Agent 核心逻辑
└── app.py            # Streamlit 前端界面

3. 环境准备

安装依赖:

pip install langchain langchain-openai langchain-experimental pandas matplotlib streamlit python-dotenv

在项目根目录创建 .env 文件,存放 DeepSeek API Key(仅用于演示,生产环境应使用更安全的密钥管理方案):

DEEPSEEK_API_KEY=your-api-key-here

如果你使用的是 OpenAI 官方接口,只需将 openai_api_base 改为官方地址,model 改为 gpt-4 等模型即可。

4. Agent 核心实现(agent.py)

Agent 是整个应用的"大脑",它负责接收用户的自然语言问题,转化为可执行的 Python 代码并运行。

# agent.py
import os
import pandas as pd
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_experimental.tools.python.tool import PythonAstREPLTool
from dotenv import load_dotenv

load_dotenv()

# 1. 初始化 LLM —— 使用 DeepSeek 兼容接口
llm = ChatOpenAI(
    model="deepseek-chat",
    openai_api_key=os.getenv("DEEPSEEK_API_KEY"),
    openai_api_base="https://api.deepseek.com/v1",
    temperature=0,
)


def create_agent_with_data(df: pd.DataFrame):
    """基于给定的 DataFrame 创建一个数据分析 Agent"""

    # 将 DataFrame 注入到 Python 执行环境中
    tools = [PythonAstREPLTool(locals={"df": df})]

    system_prompt = f"""
    你是一个数据分析助手。你有一个名为 `df` 的 pandas DataFrame 变量。
    你可以通过生成并执行 Python 代码来回答用户的问题。

    如果用户要求画图,请将图表保存为 'plot.png'。

    当你获得足够的数据后,给出最终答案。

    df 的前几行数据如下:
    {df.head().to_markdown()}
    """

    agent = create_agent(
        model=llm,
        tools=tools,
        system_prompt=system_prompt,
    )

    return agent

几个关键设计点

要点 说明
PythonAstREPLTool 来自 langchain-experimental,能让 LLM 在沙盒中执行 Python 代码
locals={"df": df} 把用户上传的 DataFrame 注入工具环境,让 Agent 可以直接操作 df 变量
system_prompt 中的 df.head() 作为上下文预注入,帮助 LLM 理解数据结构和列名,减少试错
temperature=0 数据分析场景需要稳定可复现的结果,设为 0 避免随机性

5. Streamlit 前端实现(app.py)

前端负责提供文件上传、聊天交互和图表展示功能。

# app.py
import streamlit as st
import pandas as pd
import os
from agent import create_agent_with_data

st.set_page_config(page_title="数据分析智能助手", layout="wide")
st.title("🤖 数据分析智能助手")

# 初始化 session state
if "messages" not in st.session_state:
    st.session_state.messages = []
if "df" not in st.session_state:
    st.session_state.df = None

# --- 侧边栏:数据管理 ---
with st.sidebar:
    st.header("📊 数据管理")
    uploaded_file = st.file_uploader("上传 CSV 文件", type=["csv"])

    if uploaded_file is not None:
        st.session_state.df = pd.read_csv(uploaded_file)
        st.success(
            f"✅ 成功加载数据,共 {st.session_state.df.shape[0]} 行,"
            f"{st.session_state.df.shape[1]} 列"
        )
        st.dataframe(st.session_state.df.head())

    if st.button("🗑️ 清除数据"):
        st.session_state.df = None
        st.session_state.messages = []
        st.rerun()

# --- 主区域:聊天 ---
if st.session_state.df is not None:
    # 显示聊天历史
    for message in st.session_state.messages:
        with st.chat_message(message["role"]):
            st.markdown(message["content"])

    # 用户输入
    if prompt := st.chat_input("输入你的数据分析需求..."):
        # 添加用户消息
        st.session_state.messages.append({"role": "user", "content": prompt})
        with st.chat_message("user"):
            st.markdown(prompt)

        # 调用 Agent 并获取响应
        with st.chat_message("assistant"):
            with st.spinner("🤔 思考中..."):
                try:
                    agent = create_agent_with_data(st.session_state.df)
                    response = agent.invoke(
                        {"messages": [{"role": "user", "content": prompt}]}
                    )
                    reply = response["messages"][-1].content
                    st.markdown(reply)
                    st.session_state.messages.append(
                        {"role": "assistant", "content": reply}
                    )

                    # 如果生成了图表,在聊天框下方展示
                    if os.path.exists("plot.png"):
                        st.image("plot.png")
                        os.remove("plot.png")

                except Exception as e:
                    st.error(f"❌ 出错了:{e}")
else:
    st.info("👈 请先在左侧上传 CSV 文件开始分析")

核心交互流程

用户上传 CSV 文件

pandas 读取为 DataFrame

存入 st.session_state.df

用户输入自然语言问题

Agent 生成 Python 代码

PythonAstREPLTool 执行代码

是否包含绘图?

将图表保存为 plot.png

直接返回计算结果

Streamlit 展示图表

展示分析结果

6. 运行与演示

在项目目录下启
启动后,浏览器访问 http://localhost:8501,你会看到如下界面效果:
在这里插入图片描述

💡 实际效果:左侧边栏上传 CSV → 主区域像聊天一样提问 → Agent 实时返回分析结果或图表。
动应用:

streamlit run app.py

示例对话

上传一份销售数据 CSV 后,你可以这样与助手互动:

用户输入 Agent 输出
“这个表有哪些列?” 列出所有列名及数据类型
“帮我计算每个月的总销售额” 按月份 groupby 后求和,返回表格
“画一张月度销售趋势折线图” 生成 plot.png 并在界面展示
“哪个品类的利润率最高?” 计算后给出具体答案

7. 注意事项

  • API 调用次数:Agent 在执行过程中可能多次调用 LLM,复杂问题会消耗较多 Token,建议设置合理的 API 额度预警。
  • 代码安全性PythonAstREPLTool 在受限环境中执行,但仍应避免在生产环境直接暴露给不可信用户。
  • 图表管理:每次生成 plot.png 后都会删掉原文件,避免下次展示旧图。
  • 会话状态st.session_state 保持聊天记录和数据跨轮次持久化,点击"清除数据"会重置一切。

8. 扩展思路

  • 支持更多数据源:扩展为支持 Excel、JSON、数据库查询
  • 历史对话记忆:引入 LangChain 的 Memory 模块,让 Agent 记住之前的分析上下文
  • 多轮交互优化:让 Agent 在信息不足时主动反问,而非直接报错
  • 切换模型:将 ChatOpenAI 替换为 ChatAnthropic 使用 Claude,或接入本地 Ollama 模型

9.本文实现了一个从数据上传到自然语言分析、从代码生成到可视化输出的完整 Demo 链路。LangChain Agent 负责调度 LLM 与代码执行工具,Streamlit 提供了开箱即用的聊天式 UI,DeepSeek 的 OpenAI 兼容接口降低了接入门槛。整个项目不到 100 行核心代码,即可拥有一个能听懂人话的数据分析助手。析助手。

你可以在此基础上快速定制自己的分析场景,让数据探索变得像聊天一样简单。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐