之前去一家公司面试,岗位是AI协助岗,内容是搭建智能体整理下Excel生成PPT,最后因为不收实习生给我拒了,但是我回去后思考了一下,感觉这个并不难,于是尝试自己写了一下。

很多刚接触 AI 辅助编程的朋友都会遇到一个困境:我们在 IDE(比如 Cursor、OpenCode 或 VS Code 的 Continue 插件)里接入了强大的本地开源模型(如 Gemma 26B 或 Llama 3),原本指望它能像一个真正的“智能体(Agent)”一样帮我们统揽全局、自动改代码、处理文件,结果却发现它经常“已读不回”、报错,甚至连本地文件夹都死活读不出来。

为什么会这样? 因为 IDE 插件里的“Agent 模式”往往会向大模型发送极其复杂的后台系统指令。本地开源模型虽然懂代码,但在处理这种严格的“工具调用(Tool Calling)”格式时,很容易格式错乱导致死循环。

破局之道:跳出聊天框,亲手“手搓”一个智能体工作流! 真正的智能体不应该只是一个“带快捷键的网页对话框”,它必须拥有操作系统的读写权限。今天,我们就利用 Python + CrewAI + Ollama,在完全断网的本地环境下,搭建一个由两个数字打工人组成的“AI 财务团队”。

我们的目标: 给它一份生硬的 Excel 业绩报表,它不仅能自动算出本月销冠、对比增长,还能自己画出数据柱状图,最后排版成一份精美的多页 PowerPoint 演示文稿!


🛠️ 准备工作

在开始之前,你需要确保电脑上安装了以下基础环境:

  1. Ollama:并在后台运行了一个本地大模型(本教程以 gemma4:26b 为例,如果电脑配置有限,强烈推荐使用 llama3.1:8bqwen2.5-coder:7b)。

  2. Anaconda / Miniconda:用于隔离 Python 环境,防止包冲突。

第一步:搭建专属虚拟环境

打开你的终端(Anaconda Prompt 或 Git Bash),我们为这个项目建一个专属的“房间”并安装所有必需的库:

# 1. 创建名为 agent_env 的环境,指定 Python 3.10
conda create -n agent_env python=3.10 -y

# 2. 激活环境
conda activate agent_env

# 3. 安装智能体框架和数据处理工具
pip install crewai crewai-tools pandas python-pptx matplotlib openpyxl

💻 核心逻辑拆解

我们不写面条代码,而是要像当老板一样,定义工具、招募员工、派发任务

1. 移花接木:将算力指向本地大模型

CrewAI 默认会去寻找国外的 OpenAI 接口。我们需要在代码的最开头加上这三行代码,强行把请求拦截并重定向到本地的 Ollama 服务:

import os
os.environ["OPENAI_API_BASE"] = "http://127.0.0.1:11434/v1"
os.environ["OPENAI_MODEL_NAME"] = "gemma4:26b" # 替换为你下载的模型名
os.environ["OPENAI_API_KEY"] = "ollama"        # 随便填,不能留空

2. 打造工具 (Tools):赋予 AI 手和脚

大模型本身是个“纯文科生”,不会算数也不会画图。我们需要用 Python 写好工具函数,并用 @tool 装饰器封装起来,让 AI 在需要时调用。

在本例中,我们需要两个核心工具:

  • read_excel_tool:利用 pandas 读取 Excel,并转换成 AI 能看懂的纯文本摘要。

  • create_advanced_ppt_tool:利用 matplotlib 生成数据柱状图,再利用 python-pptx 把 AI 写的总结文案和图片一起塞进幻灯片里。

(注:为避免最新的 pydantic 报错,一定要使用 from crewai.tools import tool,千万别用 langchain 的同名装饰器!)

3. 招募员工 (Agents) 与分配任务 (Tasks)

为了防止 AI “脑容量过载”把事情搞砸,我们将任务拆分给两位专家:

  • 角色 A:资深数据分析师。任务:读取表格,算出累计收入最高的人,并提炼 3 条具体的财务结论。

  • 角色 B:幻灯片排版总监。任务:拿到分析师的结论后,不准擅自篡改数据,立刻调用 PPT 绘制工具生成最终文件。


🚀 见证奇迹:完整执行代码

新建一个名为 run_agent.py 的文件,将以下完整代码粘贴进去。这段代码自带了“自动生成测试 Excel”的贴心功能,你直接运行即可看到效果。

import os
import pandas as pd
import matplotlib.pyplot as plt
from pptx import Presentation
from pptx.util import Inches, Pt
from crewai import Agent, Task, Crew
from crewai.tools import tool

# 解决 matplotlib 画图时中文显示为方块的问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei'] 
plt.rcParams['axes.unicode_minus'] = False 

# ==========================================
# 0. 自动生成测试用的 Excel 数据
# ==========================================
def create_sample_excel():
    if not os.path.exists("data.xlsx"):
        print("📊 正在自动生成测试文件 data.xlsx...")
        data = {
            "姓名": ["张三", "李四", "王五", "赵六"],
            "上周收入": [1200, 2500, 1800, 3000],
            "本月累计收入": [4500, 8800, 6200, 9500],
            "上月收入": [4000, 8000, 6000, 9000]
        }
        pd.DataFrame(data).to_excel("data.xlsx", index=False)
        print("✅ 测试数据准备完毕!\n")

create_sample_excel()

# ==========================================
# 1. 核心配置:将算力指向本地模型
# ==========================================
os.environ["OPENAI_API_BASE"] = "http://127.0.0.1:11434/v1"
os.environ["OPENAI_MODEL_NAME"] = "gemma4:26b" # 建议根据显存调整
os.environ["OPENAI_API_KEY"] = "ollama"

# ==========================================
# 2. 打造高级工具
# ==========================================
@tool("读取Excel工具")
def read_excel_tool(file_path: str) -> str:
    """读取指定路径的Excel文件,并返回数据摘要供分析使用。"""
    try:
        return pd.read_excel(file_path).to_string() 
    except Exception as e:
        return f"读取失败: {e}"

@tool("高级PPT排版与绘图工具")
def create_advanced_ppt_tool(analysis_summary: str) -> str:
    """
    接收分析师的文本总结,自动读取数据绘制柱状图,
    并生成包含封面、图表页、总结页的精美多页 PPT。
    """
    try:
        # 1. 读取数据并画图保存到本地
        df = pd.read_excel("data.xlsx")
        plt.figure(figsize=(8, 4.5))
        plt.bar(df['姓名'], df['本月累计收入'], color='#4F81BD', edgecolor='black')
        plt.title('本月员工累计收入排行榜', fontsize=16)
        plt.ylabel('收入 (元)', fontsize=12)
        plt.grid(axis='y', linestyle='--', alpha=0.7)
        
        chart_filename = "temp_chart.png"
        plt.savefig(chart_filename, bbox_inches='tight', dpi=150)
        plt.close()

        # 2. 开始构建 PPT
        prs = Presentation()
        
        # --- 第1页:高大上的封面 ---
        slide_1 = prs.slides.add_slide(prs.slide_layouts[0])
        slide_1.shapes.title.text = "财务业绩自动化分析报告"
        slide_1.placeholders[1].text = "生成者:本地 AI 智能体小分队\n数据来源:data.xlsx"
        
        # --- 第2页:数据可视化 ---
        slide_2 = prs.slides.add_slide(prs.slide_layouts[5]) 
        slide_2.shapes.title.text = "图表直击:本月收入排行"
        slide_2.shapes.add_picture(chart_filename, Inches(1), Inches(2), width=Inches(8))

        # --- 第3页:智能分析结论 ---
        slide_3 = prs.slides.add_slide(prs.slide_layouts[1]) 
        slide_3.shapes.title.text = "本月业绩核心洞察"
        tf = slide_3.placeholders[1].text_frame
        tf.word_wrap = True
        tf.text = analysis_summary # 直接塞入大模型写好的总结

        prs.save("高级财务汇报.pptx")
        if os.path.exists(chart_filename): os.remove(chart_filename)
        return "成功!精美的多页 PPT '高级财务汇报.pptx' 已生成。"
    except Exception as e:
        return f"PPT生成失败: {e}"

# ==========================================
# 3. 招募员工
# ==========================================
data_analyst = Agent(
    role='资深数据分析师',
    goal='精确读取 Excel 数据,找出本月累计收入最高的人,并计算其对比上月的增长额。',
    backstory='你是一个极其细心的财务专家,善于用要点罗列核心结论。',
    verbose=True,
    allow_delegation=False,
    tools=[read_excel_tool]
)

ppt_designer = Agent(
    role='幻灯片排版总监',
    goal='接收分析师的结论,直接调用【高级PPT排版与绘图工具】生成文件。',
    backstory='你是个行动派,拿到文案后第一时间调用工具生成 PPT。',
    verbose=True,
    allow_delegation=False,
    tools=[create_advanced_ppt_tool]
)

# ==========================================
# 4. 派发任务
# ==========================================
task1 = Task(
    description='使用【读取Excel工具】读取 data.xlsx。分析谁本月累计收入最高,并写出3条具体的、带有数字支持的结论。',
    expected_output='一段逻辑清晰的财务分析总结(纯文本)。',
    agent=data_analyst
)

task2 = Task(
    description='接收数据分析师写好的总结,作为参数调用【高级PPT排版与绘图工具】。',
    expected_output='确认 PPT 已生成的成功提示。',
    agent=ppt_designer
)

# ==========================================
# 5. 启动项目
# ==========================================
my_crew = Crew(agents=[data_analyst, ppt_designer], tasks=[task1, task2], verbose=True)

print("🚀 智能体团队开始工作!坐和放宽,让显卡飞一会儿...")
my_crew.kickoff()
print("\n🎉 任务全部结束!快去当前文件夹看看你的战利品吧!")

执行命令

确保你处于 agent_env 环境下,在终端中运行:

python run_agent.py

终端会像看电影一样实时打印出这两个智能体的“内心独白”和调用工具的过程。当出现任务结束的提示时,打开文件夹,一份包含封面、漂亮图表和专业分析结论的 高级财务汇报.pptx 就静静地躺在那里了。

这样就能够实现简易的excel文件转PPT文件的功能,如果需要其他功能也可以通过改变对智能体的提示词来实现,并且也可以通过优化提示词来美化自己的PPT。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐