一个基于 LangGraph 和 TypeScript 构建的智能天气分析 Agent,能够查询天气数据、提供天气预报,并根据天气情况给出个性化建议。
✨ 新增: 终端风格的前端界面!查看 Terminal Frontend 部分。
# 安装后端依赖
npm install
# 安装前端依赖(可选)
cd front-end
npm install
cd ..复制 .env.example 到 .env 并配置你的 LLM API Key:
cp .env.example .env然后编辑 .env 文件,选择一个 LLM 提供商并设置 API Key:
# 使用 Anthropic Claude(推荐)
LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-your_api_key_here
ANTHROPIC_MODEL=claude-3-5-sonnet-20241022
# 或使用 OpenAI
# LLM_PROVIDER=openai
# OPENAI_API_KEY=sk-your_api_key_here
# OPENAI_MODEL=gpt-4o
# 或使用 DeepSeek(性价比高)
# LLM_PROVIDER=deepseek
# DEEPSEEK_API_KEY=your_deepseek_api_key_here
# DEEPSEEK_MODEL=deepseek-chat💡 提示: 详细配置指南请查看 docs/LLM_SETUP.md
# 运行所有示例
npm run dev
# 交互式模式
npm run dev interactive
# 查询指定城市的天气
npm run dev weather Beijing# 启动 API 服务器
npm run start:api
# 或开发模式
npm run dev:apiAPI 将在 http://localhost:3000 上运行。
# 进入前端目录
cd front-end
# 启动开发服务器
npm run dev终端界面将在 http://localhost:3001 上运行。
# 使用提供的一键启动脚本
chmod +x start-all.sh
./start-all.sh这将同时启动 API 服务器(端口 3000)和终端前端(端口 3001)。
# 快速测试配置是否正确
npx tsx src/index.ts weather Beijing你应该看到类似的输出:
============================================================
示例 1: 查询当前天气
============================================================
查询北京的当前天气...
✅ LLM 配置验证通过
🔧 LLM Configuration:
{
"provider": "anthropic",
"model": "claude-3-5-sonnet-20241022",
"temperature": 0.7,
"maxTokens": 1024
}
...
- 🤖 智能对话: 基于 Claude AI 模型的自然语言理解
- 🌤️ 天气查询: 实时查询全球城市的当前天气
- 📅 天气预报: 获取未来 5 天的天气预报
- 💡 智能分析: 根据天气数据提供穿衣、出行、活动建议
- 🔧 可扩展架构: 基于 LangGraph 的模块化设计,易于扩展
- 📦 TypeScript 支持: 完整的类型定义和类型安全
- 🎨 丰富的工具: 集成多种天气工具(模拟数据 + 真实 API)
langgraph-demo/
├── src/
│ ├── graph/
│ │ └── weatherAgent.ts # LangGraph 核心逻辑
│ ├── tools/
│ │ └── weather.ts # 天气工具实现
│ ├── types/
│ │ └── index.ts # TypeScript 类型定义
│ ├── api/
│ │ └── server.ts # REST API 服务器
│ └── index.ts # 主入口文件
├── front-end/ # 🆕 终端风格前端
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx # 终端界面
│ │ └── globals.css # 终端样式
│ └── package.json
├── docs/ # 📚 完整文档
│ ├── LLM_SETUP.md
│ ├── DEPLOYMENT.md
│ ├── BUG_FIXES.md
│ ├── FRONTEND_QUICKSTART.md
│ └── SUMMARY.md
├── scripts/
│ └── test-config.ts
├── package.json
├── tsconfig.json
├── .env.example
└── README.md
- LangGraph: 图结构化的 AI Agent 框架
- LangChain: AI 应用开发框架
- Anthropic Claude: 强大的语言模型
- TypeScript: 类型安全的 JavaScript
- OpenWeatherMap API: 真实天气数据源(可选)
- Zod: 运行时类型验证
- Node.js >= 18.0.0
- npm 或 pnpm 或 yarn
- LLM API Key(必需)- 支持多种提供商:
- Anthropic Claude
- OpenAI GPT-4
- DeepSeek(推荐,性价比高)
- 通义千问
- Ollama(本地模型)
- 自定义 OpenAI 兼容端点
- OpenWeatherMap API Key(可选,用于真实天气数据)
📘 查看 LLM_PROVIDERS.md 了解详细的提供商配置指南
- 克隆项目
cd /Users/nick/desk/test/langgraph-demo- 安装依赖
npm install
# 或
pnpm install
# 或
yarn install- 配置环境变量
cp .env.example .env编辑 .env 文件,选择 LLM 提供商并配置对应的 API Key:
# 选择 LLM 提供商 (可选值: anthropic, openai, deepseek, qwen, ollama, custom)
# 默认: anthropic
LLM_PROVIDER=anthropic
# Anthropic Claude 配置
ANTHROPIC_API_KEY=your_anthropic_api_key_here
ANTHROPIC_MODEL=claude-3-sonnet-20240229
# OpenAI 配置(如果使用 OpenAI)
# OPENAI_API_KEY=your_openai_api_key_here
# OPENAI_MODEL=gpt-4o
# DeepSeek 配置(推荐,性价比高)
# DEEPSEEK_API_KEY=your_deepseek_api_key_here
# DEEPSEEK_MODEL=deepseek-chat
# 通义千问配置(如果使用 Qwen)
# QWEN_API_KEY=your_qwen_api_key_here
# QWEN_MODEL=qwen-plus
# Ollama 配置(本地模型)
# OLLAMA_BASE_URL=http://localhost:11434/v1
# OLLAMA_MODEL=llama3.2
# OpenWeatherMap API Key(可选,用于真实天气数据)
OPENWEATHERMAP_API_KEY=your_openweathermap_api_key_here
# 模型配置
TEMPERATURE=0.7
MAX_TOKENS=1024💡 推荐配置:
- 开发测试:使用 DeepSeek(免费额度 + 性价比高)
- 生产环境:使用 DeepSeek 或 Claude 3.5
- 本地部署:使用 Ollama(完全免费,隐私安全)
详细配置说明请查看 LLM_PROVIDERS.md
- 编译项目
npm run build启动交互式命令行界面:
npm run dev
# 或
node dist/index.js interactive在交互模式中,你可以:
- 输入天气相关问题进行查询
- 输入
help查看帮助 - 输入
examples查看示例问题 - 输入
graph查看图结构 - 输入
exit退出
示例对话:
🤖 请输入您的问题 (或输入 'exit' 退出): 北京现在什么天气?
🤖 正在查询: 北京现在什么天气?
✅ 查询完成
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📍 **Beijing, CN**
🌡️ **温度**: 22°C (体感 20°C)
💧 **湿度**: 65%
🌬️ **风速**: 3.5 m/s
📊 **气压**: 1015 hPa
👁️ **能见度**: 10 km
🌤️ **天气状况**: 晴朗
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 统计信息:
执行时间: 2345ms
迭代次数: 2
使用的工具:
✓ get_weather
运行所有内置示例:
npm run dev examples
# 或
node dist/index.js examples这将依次执行以下示例:
- 示例 1: 查询当前天气
- 示例 2: 查询天气预报
- 示例 3: 天气分析和建议
- 示例 4: 流式查询
- 示例 5: 自定义配置
查看 LLM 提供商切换示例:
npx tsx src/examples/switch-provider.ts这将展示如何在不同 LLM 提供商之间切换,包括:
- 使用预设配置快速切换
- 从环境变量动态加载配置
- 根据任务类型智能选择提供商
- 比较不同提供商的性能
- 使用自定义 OpenAI 兼容提供商
直接查询指定城市的天气:
npm run dev weather Beijing
# 或
node dist/index.js weather Shanghaiimport { createWeatherAgent } from './graph/weatherAgent.js';
// 创建 Agent
const agent = createWeatherAgent();
// 查询天气
const result = await agent.query('查询北京的天气');
console.log(result.finalMessage);
console.log('使用的工具:', result.toolsUsed);
console.log('执行时间:', result.executionTime + 'ms');import { createWeatherAgent } from './graph/weatherAgent.js';
const agent = createWeatherAgent();
// 流式执行
for await (const event of agent.streamQuery('查询上海的天气')) {
for (const [nodeName, nodeOutput] of Object.entries(event)) {
console.log(`节点 [${nodeName}] 执行完成`);
// 处理节点输出...
}
}import { createWeatherAgent } from './graph/weatherAgent.js';
import { PresetConfigs } from './config/llm.js';
// 方法 1: 使用预设配置(推荐)
const agent = createWeatherAgent({
...PresetConfigs.deepseekV3, // 使用 DeepSeek 预设
apiKey: 'your_deepseek_api_key',
});
// 方法 2: 完全自定义配置
const customAgent = createWeatherAgent({
provider: 'deepseek',
model: 'deepseek-chat',
apiKey: 'your_api_key',
temperature: 0.5,
maxTokens: 2048,
maxIterations: 5,
verbose: true,
});
// 方法 3: 使用不同的提供商
const claudeAgent = createWeatherAgent({
...PresetConfigs.claude35Sonnet,
apiKey: 'your_anthropic_api_key',
});
const openaiAgent = createWeatherAgent({
...PresetConfigs.gpt4o,
apiKey: 'your_openai_api_key',
});
// 使用配置查询
const result = await agent.query('杭州现在的天气怎么样?');支持的预设配置:
PresetConfigs.claude3Sonnet- Claude 3 SonnetPresetConfigs.claude35Sonnet- Claude 3.5 Sonnet(最新)PresetConfigs.gpt4o- GPT-4oPresetConfigs.deepseekV3- DeepSeek V3(推荐)PresetConfigs.qwenPlus- 通义千问 PlusPresetConfigs.ollamaLlama3- Ollama Llama 3.2
详细配置请查看 LLM_PROVIDERS.md
import {
queryWeather,
getCurrentWeather,
getWeatherForecast,
analyzeWeatherWithAdvice
} from './graph/weatherAgent.js';
// 快速查询天气
const result = await queryWeather('查询北京的天气');
// 获取当前天气
const current = await getCurrentWeather('Shanghai', 'metric');
// 获取天气预报
const forecast = await getWeatherForecast('Tokyo', 5);
// 分析天气并提供建议
const analysis = await analyzeWeatherWithAdvice('Shenzhen');本项目支持多种 LLM 提供商,通过 OpenAI 兼容规范实现无缝切换:
| 提供商 | 推荐度 | 特点 | 适合场景 |
|---|---|---|---|
| DeepSeek | ⭐⭐⭐⭐⭐ | 性价比极高,中文优秀 | 开发、生产 |
| Claude 3.5 | ⭐⭐⭐⭐⭐ | 最强理解和推理 | 复杂分析 |
| OpenAI GPT-4 | ⭐⭐⭐⭐ | 综合能力强,生态完善 | 通用场景 |
| 通义千问 | ⭐⭐⭐⭐ | 中文优化,企业级支持 | 企业应用 |
| Ollama | ⭐⭐⭐ | 完全本地,隐私安全 | 本地部署 |
| 自定义 | ⭐⭐⭐ | 支持任何兼容端点 | 特殊需求 |
方法 1: 修改 .env 文件
# 切换到 DeepSeek
LLM_PROVIDER=deepseek
DEEPSEEK_API_KEY=sk-xxxxx
# 切换到 OpenAI
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-xxxxx
# 切换到 Ollama(本地)
LLM_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434/v1
OLLAMA_MODEL=llama3.2方法 2: 代码中指定
import { createWeatherAgent, PresetConfigs } from './graph/weatherAgent.js';
// 使用 DeepSeek
const agent = createWeatherAgent({
...PresetConfigs.deepseekV3,
apiKey: 'sk-xxxxx',
});
// 使用 Claude
const claudeAgent = createWeatherAgent({
...PresetConfigs.claude35Sonnet,
apiKey: 'sk-ant-xxxxx',
});| 模型 | 响应速度 | 成本 | 质量 | 推荐指数 |
|---|---|---|---|---|
| DeepSeek | 2.5s | ⭐ | ⭐⭐⭐⭐⭐ | 9.5 |
| Claude 3.5 | 3.5s | ⭐⭐ | ⭐⭐⭐⭐⭐ | 9.8 |
| GPT-4o | 3.2s | ⭐⭐ | ⭐⭐⭐⭐⭐ | 9.5 |
| Qwen Plus | 2.8s | ⭐⭐ | ⭐⭐⭐⭐ | 9.0 |
| Ollama | 1.5s | ⭐⭐⭐ | ⭐⭐⭐ | 7.5 |
📘 详细配置指南: LLM_PROVIDERS.md 🎯 切换示例: src/examples/switch-provider.ts
查询指定城市的实时天气信息。
参数:
city: 城市名称(必需)units: 温度单位,可选值:metric(摄氏度),imperial(华氏度),kelvin(开尔文)
示例:
查询北京的天气
上海现在什么天气
纽约现在的温度,使用华氏度
获取指定城市的未来天气预报。
参数:
city: 城市名称(必需)days: 预报天数,默认 5 天units: 温度单位
示例:
查看北京未来3天的天气预报
上海下周天气怎么样
纽约未来5天会下雨吗
基于天气数据提供详细分析和建议。
参数:
weatherData: 天气数据的 JSON 字符串includeRecommendations: 是否包含建议,默认 true
示例:
分析一下今天的天气,给点建议
根据天气情况,我应该穿什么衣服
今天的天气适合户外运动吗
| 变量名 | 说明 | 默认值 | 必需 |
|---|---|---|---|
ANTHROPIC_API_KEY |
Anthropic API 密钥 | - | ✅ |
OPENWEATHERMAP_API_KEY |
OpenWeatherMap API 密钥 | - | ❌ |
DEFAULT_MODEL |
默认模型 | claude-3-sonnet-20240229 |
❌ |
TEMPERATURE |
温度参数 | 0.7 |
❌ |
MAX_TOKENS |
最大 token 数 | 1024 |
❌ |
DEFAULT_CITY |
默认城市 | Beijing |
❌ |
DEFAULT_UNITS |
默认温度单位 | metric |
❌ |
LOG_LEVEL |
日志级别 | info |
❌ |
interface AgentConfig {
model: string; // 模型名称
temperature: number; // 温度参数 (0-1)
maxTokens: number; // 最大 token 数
tools: Tool[]; // 可用工具列表
systemPrompt: string; // 系统提示词
maxIterations?: number; // 最大迭代次数
verbose?: boolean; // 是否启用详细日志
}- 个人天气助手: 查询每日天气,获取穿衣建议
- 出行规划: 查询目的地天气,制定旅行计划
- 活动安排: 根据天气情况安排户外活动
- 农业指导: 提供农业气象建议
- 健康管理: 根据天气提供健康建议
- 北京现在什么天气?
- 查询上海的实时天气
- 东京现在的温度是多少?
- 伦敦今天天气怎么样?
- 北京未来3天会下雨吗?
- 查看上海下周的天气预报
- 纽约未来5天的温度变化
- 东京周末的天气怎么样?
- 分析一下今天的天气,给点建议
- 根据北京现在的天气,我应该穿什么衣服?
- 今天适合户外运动吗?
- 深圳的天气对出行有什么影响?
# 1. 编辑 .env 文件
vim .env
# 2. 修改提供商
LLM_PROVIDER=deepseek
# 3. 配置 DeepSeek API Key
DEEPSEEK_API_KEY=sk-xxxxx
# 4. 运行程序
npm run dev# 1. 安装 Ollama
brew install ollama
# 2. 拉取模型
ollama pull llama3.2
# 3. 编辑 .env
LLM_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434/v1
OLLAMA_MODEL=llama3.2
# 4. 运行程序
npm run devimport { createWeatherAgent, PresetConfigs } from './graph/weatherAgent.js';
// 根据任务类型选择提供商
function getAgentForTask(task: string) {
if (task.includes('简单查询')) {
return createWeatherAgent({
...PresetConfigs.deepseekV3,
apiKey: process.env.DEEPSEEK_API_KEY,
});
}
if (task.includes('复杂分析')) {
return createWeatherAgent({
...PresetConfigs.claude35Sonnet,
apiKey: process.env.ANTHROPIC_API_KEY,
});
}
return createWeatherAgent(); // 使用默认配置
}
// 使用
const agent = getAgentForTask('简单查询北京天气');📘 更多示例和详细说明: LLM_PROVIDERS.md
src/
├── graph/
│ └── weatherAgent.ts # LangGraph 核心实现
├── tools/
│ └── weather.ts # 天气工具集
├── types/
│ └── index.ts # TypeScript 类型定义
└── index.ts # 主入口和示例
- Agent Node: 处理用户输入,决定是否调用工具
- Tools Node: 执行具体的工具调用
- Conditional Edge: 根据执行结果决定下一步
- State: 在节点之间传递的状态数据
要添加新的工具,创建一个新的工具类:
import { StructuredTool } from "@langchain/core/tools";
import { z } from "zod";
export class MyCustomTool extends StructuredTool {
name = "my_custom_tool";
description = "工具描述";
schema = z.object({
param1: z.string().describe("参数1"),
param2: z.number().optional().describe("参数2"),
});
async _call(input: z.infer<typeof this.schema>): Promise<string> {
// 实现工具逻辑
return "结果";
}
}然后将工具添加到 Agent:
import { createWeatherAgent } from './graph/weatherAgent.js';
const agent = createWeatherAgent();
agent.addTool(new MyCustomTool());constructor(config?: Partial<AgentConfig>)query(prompt: string): Promise<AgentResult>- 执行查询streamQuery(prompt: string): AsyncGenerator- 流式查询getConfig(): AgentConfig- 获取配置updateSystemPrompt(prompt: string): void- 更新系统提示getTools(): Tool[]- 获取工具列表addTool(tool: Tool): void- 添加工具getGraphVisualization(): Promise<string>- 获取图结构
详细类型定义请参考 src/types/index.ts
1. API Key 未配置
Error: Anthropic API key not found
解决:在 .env 文件中设置 ANTHROPIC_API_KEY
2. 网络请求失败
Error: Weather API error: Network error
解决:程序会自动使用模拟数据,或者配置 OPENWEATHERMAP_API_KEY
3. 模块未找到
Error: Cannot find module '...'
解决:运行 npm install 安装依赖
欢迎贡献!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
本项目采用 MIT 许可证 - 详见 LICENSE 文件
- LangChain - 强大的 AI 应用框架
- LangGraph - 图结构化的 AI Agent 框架
- Anthropic - 提供强大的 Claude AI 模型
- OpenWeatherMap - 提供天气数据 API
如有问题或建议,欢迎通过以下方式联系:
- 提交 Issue
- 发送邮件至 nick328775856@gamil.com
如果这个项目对你有帮助,请给它一个 ⭐️
注意: 本项目仅供学习和演示使用。在生产环境中使用前,请确保:
- 妥善保管 API 密钥
- 实现适当的错误处理
- 添加请求限流
- 实现缓存机制
- 添加监控和日志