Skip to content

penglisha/data-analysis-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

数据分析 Agent —— 学习项目

用 Python + Ollama 本地模型实现的自主数据分析 Agent,采用标准 ReAct 模式。 完全离线运行,无需 API Key,无需联网。


1. 环境配置步骤

第一步:安装并启动 Ollama

  1. 前往 ollama.com 下载并安装 Ollama(支持 macOS / Windows / Linux)

  2. 拉取模型(gemma4:e4b 约 9.6 GB,首次下载需要等待):

    ollama pull gemma4:e4b
  3. 启动 Ollama 服务(安装后通常会自动运行,也可以手动启动):

    ollama serve
  4. 验证服务正常:

    curl http://localhost:11434/api/tags
    # 应该返回包含 gemma4:e4b 的 JSON

第二步:安装 Python 依赖

# 进入项目目录
cd agent

# 建议先创建虚拟环境,保持系统 Python 环境整洁
python -m venv .venv
source .venv/bin/activate      # macOS / Linux
# .venv\Scripts\activate       # Windows

# 安装依赖
pip install -r requirements.txt

第三步:配置(可选)

默认配置开箱即用,不需要修改。如果想换模型,才需要:

cp .env.example .env
# 编辑 .env,修改 OLLAMA_MODEL

运行

python main.py
# 或直接双击 run.sh(自动创建虚拟环境)

2. 为什么选择 Ollama 本地模型?

对比项 Ollama 本地 云端 API(Gemini / Claude)
费用 免费,无限次数 有配额限制或按量付费
隐私 数据不离开本机 数据上传到云端
网络 完全离线可用 需要稳定的国际网络
速度 取决于本机 GPU/CPU 通常更快(云端算力)
模型能力 7B 参数,够用 更强的大模型

当前默认模型gemma4:e4b

  • 9.6 GB,中文理解和生成质量更好
  • 需要 16GB+ 内存;多轮 Agent 任务负载较高时偶尔可能触发 502

其他可选模型

ollama pull qwen2.5:7b     # 约 4.7 GB,Mac Air 8GB/16GB 更稳定,502 时可切换回此模型
ollama pull qwen2.5:1.5b   # 约 1 GB,内存极少时用
ollama pull llama3.1:8b    # Meta 出品,英文能力强

如果运行中遇到 Ollama 返回 502 错误,编辑 .env,把 OLLAMA_MODEL 改为 qwen2.5:7b 即可,代码无需修改。


3. 代码核心原理:工具调用是怎么工作的?

整体架构图

用户任务
   │
   ▼
┌──────────────────────────────────────────┐
│             Agent 核心循环               │
│                                          │
│  历史消息 ──► Ollama HTTP API            │
│   (system +      (127.0.0.1:11434)       │
│    对话记录)           │                 │
│                ┌───────┴────────┐        │
│                │                │        │
│          {"tool":"finish"} {"tool":"xxx"} │
│                │                │        │
│           任务完成         执行 Python 函数│
│                                │         │
│                         把结果追加到历史  │
│                                │         │
│                            继续下一轮     │
└──────────────────────────────────────────┘

关键机制:提示词注入工具调用

本项目不使用 Ollama 的原生 tools 参数(在 qwen2.5:7b / gemma4:e4b 上都不稳定),改为更可靠的提示词注入方式:

第一步 — 在 system prompt 里描述工具格式

你有以下工具可以使用,需要调用工具时,只输出一个 JSON 对象:
{"tool": "工具名", "args": {"参数名": "参数值"}}

可用工具:
- fetch_webpage(url: str) → 爬取网页内容
- analyze_data(data: str, question: str) → 分析数据
- save_report(content: str, filename: str) → 保存报告

任务完成后输出:
{"tool": "finish", "result": "最终总结"}

第二步 — 模型回复 JSON,代码解析执行

# 模型输出(纯文本):
{"tool": "fetch_webpage", "args": {"url": "https://news.ycombinator.com"}}

# 代码解析后执行真正的 Python 函数:
result = fetch_webpage(url="https://news.ycombinator.com")

# 把结果作为 user 消息反馈给模型:
{"role": "user", "content": "fetch_webpage 执行成功,结果如下:\n[页面内容...]"}

这种方式与模型 API 格式完全解耦,只要模型能输出 JSON 就能工作。

Ollama HTTP API 调用

代码直接调用 Ollama 的 REST API,不依赖任何第三方 SDK:

import requests

resp = requests.post(
    "http://127.0.0.1:11434/api/chat",
    json={
        "model": "gemma4:e4b",
        "messages": history,
        "stream": False,
        "keep_alive": -1,   # 防止模型在请求间隔被卸载
    },
    timeout=120,
)
content = resp.json()["message"]["content"]

ReAct 循环

ReAct = Reasoning(推理)+ Acting(行动)

Thought:我需要先爬取 HN 首页
Action:{"tool": "fetch_webpage", "args": {"url": "https://news.ycombinator.com"}}
Observation:[页面内容返回]

Thought:好的,我现在分析这些数据
Action:{"tool": "analyze_data", "args": {"data": "...", "question": "热门话题规律"}}
Observation:[分析结果返回]

Thought:分析完成,需要保存报告
Action:{"tool": "save_report", "args": {"content": "...", "filename": "hn_report.txt"}}
Observation:报告已保存

Thought:所有任务完成
Action:{"tool": "finish", "result": "今日 HN 热门话题以 AI 和云计算为主..."}

每次工具调用的结果都会成为 LLM 下一次决策的依据,这就是 Agent 能"自主"工作的原因。


4. 如何把本地模型换成 Claude API

两者的核心概念完全相同,只需替换 LLM 调用部分。

改动对比

项目 本地 Ollama Claude API
依赖 requests(内置) pip install anthropic
认证 无需 ANTHROPIC_API_KEY
调用方式 requests.post(...) client.messages.create(...)
工具调用 提示词注入 + JSON 解析 原生 tools 参数

Claude 版本的 _call_llm 核心改动

import anthropic

client = anthropic.Anthropic(api_key="your-key")

# 工具定义(Claude 原生格式,比提示词注入更精确)
tools = [
    {
        "name": "fetch_webpage",
        "description": "爬取网页内容",
        "input_schema": {
            "type": "object",
            "properties": {"url": {"type": "string"}},
            "required": ["url"]
        }
    }
]

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=4096,
    system=system_prompt,
    tools=tools,
    messages=history
)

# 检测工具调用
for block in response.content:
    if block.type == "tool_use":
        result = TOOLS[block.name](**block.input)
        history.append({
            "role": "user",
            "content": [{"type": "tool_result", "tool_use_id": block.id, "content": result}]
        })

云端大模型原生支持结构化工具调用,不需要提示词注入,可靠性更高。


5. 另一个 Agent:热点文章生成(HotArticleAgent)

除了上面的通用 ReAct Agent(agent.py),项目里还有一个编排式(Orchestration)Agent, 用于自动生成热点分析文章:agents/hot_agent.py,入口是 hot_main.py

python hot_main.py

与 ReAct Agent 的区别

项目 agent.py(ReAct) agents/hot_agent.py(编排式)
工具调用方式 LLM 自主决定调用哪个工具、何时结束 流程固定,代码直接按步骤调度
LLM 的角色 全程决策(规划 + 执行) 只负责"理解和生成"(筛选话题、写文章)
网页抓取 单个通用 fetch_webpage(url),按任务需要调用 5 个平台专用抓取函数,并发执行

完整流程

步骤1:并发抓取 5 个平台热榜(每个平台一个线程)
  ├── fetch_weibo_hot()       微博热搜
  ├── fetch_zhihu_hot()       知乎热榜
  ├── fetch_toutiao_hot()     今日头条
  ├── fetch_hackernews_hot()  Hacker News
  └── fetch_gossip_hot()      娱乐八卦(多来源降级抓取)
        │
        ▼ 合并所有热点,标注来源平台
步骤2:调用 LLM (select_topics) 从所有热点中筛选 Top N 个有价值的话题
        │
        ▼
步骤3:对每个话题调用 LLM (write_article) 生成 800-1200 字深度文章
        │
        ▼
步骤4:保存为 Markdown 文件到 output/ 目录(save_article)
        │
        ▼
步骤5:打印汇总报告(耗时、成功篇数、文件路径)

抓取阶段用 threading 并发执行 5 个平台的请求,互不阻塞,整体耗时取决于最慢的那个平台 (而不是 5 个平台耗时之和)。fetch_gossip_hot() 内部还做了多来源降级:优先从微博热搜里 按关键词过滤娱乐话题,失败则依次尝试抖音热点榜、百度热搜聚合接口。


项目文件说明

agent/
├── main.py          # 入口:启动检查、模型预热、启动 Agent
├── agent.py         # 核心:ReAct 循环、调用 Ollama API、解析 JSON、分发工具
├── tools.py         # 工具:fetch_webpage / analyze_data / save_report
├── hot_main.py      # 入口:热点文章生成 Agent(HotArticleAgent)
├── agents/
│   ├── hot_agent.py  # 编排式 Agent:并发抓取热榜 → 筛选话题 → 生成文章
│   └── hot_tools.py  # 工具:各平台热榜抓取、LLM 筛选/生成、文章保存
├── requirements.txt # 依赖列表
├── .env.example     # 配置模板(模型名称等)
├── .env             # 你的真实配置(不要提交到 Git!)
├── run.sh           # 一键运行脚本(自动创建虚拟环境)
├── reports/         # 自动创建,存放 ReAct Agent 生成的报告
└── output/          # 自动创建,存放热点文章生成 Agent 的文章

延伸学习

About

用CC手把手教我做Agent。Agent架构:感知输入 → 大模型推理 → 选择行动 → 执行工具 → 观察结果 → 循环直到完成

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors