用Python和LangChain搭建Excel处理Agent:从环境配置到完整代码

0 阅读

为什么用Python做Agent

普通Python脚本是按固定步骤执行,一步出错就中断。Agent的不同在于能自主拆解任务、动态调整步骤。比如处理Excel时,它自己决定先读取文件、再分析数据、最后生成报表,遇到异常还能反馈问题。

这种"模型决策、代码执行"的架构,让开发者用少量代码就能做出能对话的助手。本文用LangChain+OpenAI API实现,新手友好,无需本地显卡。

环境准备

需要Python 3.10+,推荐3.11。创建虚拟环境避免依赖冲突:

python -m venv agent-env
# Windows
agent-env\Scripts\activate
# Mac/Linux
source agent-env/bin/activate

安装核心包:

pip install langchain langchain-openai chromadb python-dotenv pandas openpyxl matplotlib

在项目根目录创建.env文件,写入OpenAI API Key:

OPENAI_API_KEY=sk-你的密钥

工具模块:让Agent能操作Excel

Agent本身不会直接读文件,需要我们把Python函数包装成"工具"。以下是四个核心工具,分别负责读取、分析、可视化、保存。

from langchain.tools import tool
import pandas as pd
import matplotlib.pyplot as plt
import os

@tool
def read_excel(file_path: str) -> str:
    """读取Excel文件,返回基本信息"""
    if not os.path.exists(file_path):
        return f"文件不存在:{file_path}"
    df = pd.read_excel(file_path)
    return f"读取成功:{len(df)}行,{len(df.columns)}列,字段:{list(df.columns)}"

@tool
def analyze_excel_data(file_path: str) -> str:
    """分析数值型字段的统计信息"""
    df = pd.read_excel(file_path)
    numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns
    if len(numeric_cols) == 0:
        return "无数值型字段"
    result = []
    for col in numeric_cols:
        result.append(f"{col}:均值{df[col].mean():.2f},中位数{df[col].median():.2f}")
    return "\n".join(result)

@tool
def generate_excel_report(file_path: str, save_path: str = "./report.png") -> str:
    """生成柱状图报表"""
    df = pd.read_excel(file_path)
    numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns
    if len(numeric_cols) == 0:
        return "无法生成报表"
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.figure(figsize=(10, 6))
    plt.bar(df.index, df[numeric_cols[0]])
    plt.title(f"{numeric_cols[0]}分布")
    plt.savefig(save_path, dpi=300, bbox_inches='tight')
    plt.close()
    return f"报表已保存:{save_path}"

@tool
def save_analysis_result(content: str, save_path: str = "./result.txt") -> str:
    """保存分析结果到文本文件"""
    with open(save_path, 'w', encoding='utf-8') as f:
        f.write(content)
    return f"结果已保存:{save_path}"

excel_tools = [read_excel, analyze_excel_data, generate_excel_report, save_analysis_result]

注意@tool装饰器,它让LangChain识别这些函数为Agent可调用的工具。每个工具要有清晰的docstring,Agent靠这个理解工具用途。

Agent核心:调度中心

工具准备好后,需要创建Agent来协调它们。这里用OpenAI的函数调用能力,让模型自己决定何时调用哪个工具。

from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.memory import VectorStoreRetrieverMemory
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from dotenv import load_dotenv
import os

load_dotenv()

# 初始化模型
llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    temperature=0.4,
    api_key=os.getenv("OPENAI_API_KEY")
)

# 记忆模块:用Chroma存储对话历史
embeddings = OpenAIEmbeddings()
vector_store = Chroma(
    embedding_function=embeddings,
    persist_directory="./memory",
    collection_name="excel_agent"
)
retriever = vector_store.as_retriever(search_kwargs={"k": 2})
memory = VectorStoreRetrieverMemory(
    retriever=retriever,
    memory_key="chat_history"
)

# 提示词模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是Excel处理助手,用提供的工具完成用户任务。步骤:1检查参数 2调用工具 3确认结果 4反馈用户"),
    MessagesPlaceholder(variable_name="chat_history"),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

# 创建Agent
agent = create_openai_tools_agent(llm=llm, tools=excel_tools, prompt=prompt)
agent_executor = AgentExecutor(
    agent=agent,
    tools=excel_tools,
    memory=memory,
    verbose=True  # 打印执行过程,方便调试
)

def run_agent(user_input: str):
    result = agent_executor.invoke({"input": user_input})
    return result["output"]

verbose=True很重要,新手能看到Agent每一步在想什么、调用了什么工具。

运行入口

最简单的交互循环:

from agent_core import run_agent

if __name__ == "__main__":
    print("Excel处理Agent已启动,输入'退出'结束")
    while True:
        user_input = input("\n你:")
        if user_input == "退出":
            break
        output = run_agent(user_input)
        print(f"Agent:{output}")

测试运行

准备test.xlsx,包含几列数据。运行后输入:

读取test.xlsx,分析数据,生成报表,保存分析结果

Agent会自动拆解为四步:先调用read_excel确认文件存在,再analyze_excel_data计算统计量,然后generate_excel_report画图,最后save_analysis_result保存文本。全程无需手动干预。

常见问题

API Key无效:检查.env文件是否在项目根目录,或直接用os.environ["OPENAI_API_KEY"] = "sk-xxx"硬编码测试。

中文乱码:matplotlib图表中文显示问题,已通过plt.rcParams['font.sans-serif'] = ['SimHei']设置,若仍乱码需安装SimHei字体或换用其他中文字体。

工具不被调用:检查docstring是否清晰描述参数和返回值,Agent靠这个理解工具用途。

记忆不生效:确认Chroma的persist_directory目录有写入权限,且每次对话后vector_store.persist()已调用。

扩展方向

当前是单Agent处理单文件。可扩展的方向:

  • 增加工具:Excel筛选、排序、多表合并
  • 多文件处理:让Agent批量处理文件夹内所有Excel
  • 多Agent协作:一个Agent负责读取、一个负责分析、一个负责报告,用LangGraph编排
  • 换本地模型:用Ollama运行Qwen或Llama,无需API Key但需显卡

代码已能运行,建议先修改工具函数适应自己的Excel格式,再逐步增加功能。Agent开发的核心是迭代:先跑通最小闭环,再丰富工具集。