# 实践案例00:搭建你的第一个空间AI助手 ## 目标 通过本实践,你将: 1. 配置Claude Code环境 2. 创建一个简单的空间查询技能 3. 理解Agent如何调用工具 4. 建立对后续学习的信心 --- ## 步骤1:环境准备 ### 安装Claude Code ```bash # 使用npm安装 npm install -g @anthropic-ai/claude-code # 验证安装 claude --version ``` ### 配置API密钥 ```bash # 设置API密钥 claude config set api_key your_anthropic_api_key # 或使用环境变量 export ANTHROPIC_API_KEY=your_key ``` ### 安装Python依赖 ```bash # 创建虚拟环境 python -m venv venv source venv/bin/activate # Linux/Mac # 或 venv\Scripts\activate # Windows # 安装依赖 pip install geopandas shapely matplotlib pandas ``` --- ## 步骤2:创建空间查询技能 ### 2.1 创建技能目录 ```bash mkdir -p .claude/skills ``` ### 2.2 编写技能文件 创建 `.claude/skills/spatial-query.md`: ```markdown --- name: spatial-query description: 执行基础空间查询和分析 parameters: - data_file: 空间数据文件路径 - query_type: 查询类型(buffer/intersect/nearest) - distance: 缓冲距离(用于buffer查询) --- ## 空间查询技能 当用户需要进行空间查询时,使用此技能。 ### 支持的查询类型 1. **buffer**: 缓冲区分析 2. **intersect**: 相交分析 3. **nearest**: 最近邻查找 ### 执行流程 1. 读取空间数据 2. 根据查询类型执行相应操作 3. 返回结果和统计信息 4. 可选:生成可视化 ``` --- ## 步骤3:实现技能逻辑 创建 `examples/spatial_helper.py`: ```python """ 简单的空间分析助手 演示AI如何理解并执行空间任务 """ import geopandas as gpd from shapely.geometry import Point import matplotlib.pyplot as plt class SpatialHelper: """空间分析助手类""" def __init__(self, data_path=None): self.data = None if data_path: self.load_data(data_path) def load_data(self, path): """加载空间数据""" try: self.data = gpd.read_file(path) return f"成功加载 {len(self.data)} 个空间要素" except Exception as e: return f"加载失败: {str(e)}" def buffer_analysis(self, distance, crs=None): """缓冲区分析""" if self.data is None: return "请先加载数据" if crs: # 转换到适合距离计算的坐标系 self.data = self.data.to_crs(crs) buffered = self.data.buffer(distance) result = gpd.GeoDataFrame(geometry=buffered, crs=self.data.crs) return { 'count': len(result), 'total_area': result.geometry.area.sum(), 'geometry': result } def intersect_analysis(self, other_data): """相交分析""" if self.data is None: return "请先加载数据" intersection = self.data.intersection(other_data) valid_results = intersection[~intersection.is_empty] return { 'intersecting_count': len(valid_results), 'geometries': valid_results } def nearest_neighbor(self, point, n=1): """最近邻查找""" if self.data is None: return "请先加载数据" if isinstance(point, (tuple, list)): point = Point(point) distances = self.data.geometry.distance(point) nearest_indices = distances.nsmallest(n).index results = [] for idx in nearest_indices: results.append({ 'index': idx, 'distance': distances[idx], 'geometry': self.data.loc[idx].geometry }) return results def summarize(self): """数据摘要""" if self.data is None: return "请先加载数据" return { 'count': len(self.data), 'crs': str(self.data.crs), 'bounds': self.data.total_bounds, 'geometry_types': self.data.geometry.type.value_counts().to_dict() } def visualize(self, output_path=None): """可视化""" if self.data is None: return "请先加载数据" fig, ax = plt.subplots(figsize=(10, 10)) self.data.plot(ax=ax, alpha=0.5, edgecolor='k') ax.set_title('Spatial Data Visualization') ax.set_axis_off() if output_path: plt.savefig(output_path, bbox_inches='tight', dpi=300) return f"图表已保存到 {output_path}" plt.show() return "图表已显示" # 创建一个示例数据集用于测试 def create_sample_data(): """创建示例空间数据""" import numpy as np np.random.seed(42) # 创建一些随机点 points = [Point(np.random.uniform(-100, 100), np.random.uniform(-100, 100)) for _ in range(20)] # 转换为GeoDataFrame gdf = gpd.GeoDataFrame({ 'id': range(20), 'value': np.random.randint(1, 100, 20), 'category': np.random.choice(['A', 'B', 'C'], 20) }, geometry=points, crs='EPSG:4326') # 保存为GeoJSON gdf.to_file('sample_data.geojson', driver='GeoJSON') return gdf if __name__ == "__main__": # 创建示例数据 print("创建示例数据...") create_sample_data() # 测试SpatialHelper print("\n初始化空间助手...") helper = SpatialHelper('sample_data.geojson') print("\n数据摘要:") print(helper.summarize()) print("\n缓冲区分析:") buffer_result = helper.buffer_analysis(10) print(f"缓冲区数量: {buffer_result['count']}") print(f"总缓冲面积: {buffer_result['total_area']:.2f}") print("\n最近邻查找:") nearest = helper.nearest_neighbor((0, 0), n=3) for i, n in enumerate(nearest, 1): print(f" {i}. 距离: {n['distance']:.2f}") print("\n生成可视化...") print(helper.visualize('spatial_visualization.png')) ``` --- ## 步骤4:在Claude Code中使用 ### 4.1 启动Claude Code ```bash cd /path/to/CC4SI claude ``` ### 4.2 与Claude对话 ``` 你: 我有一个空间数据文件sample_data.geojson,帮我分析一下 Claude: 让我先读取这个文件看看... [读取 sample_data.geojson] 这是一个包含20个点要素的GeoJSON文件,坐标系统为WGS84 (EPSG:4326)。 每个点都有id、value和category属性。 你想要进行什么分析? 你: 找出距离原点最近的3个点 Claude: 我来帮你找出距离原点最近的点。 [调用 spatial-query 技能] 结果: 1. 最近点 (id=7): 距离约 15.2 单位 2. 第二近点 (id=12): 距离约 23.8 单位 3. 第三近点 (id=3): 距离约 31.5 单位 需要我生成可视化吗? ``` --- ## 步骤5:理解工作原理 ### AI系统的思考过程 ``` 用户请求 ──→ [意图识别] ──→ [任务分解] │ │ ↓ ↓ 这是空间查询 需要执行: 任务 1. 加载数据 2. 计算距离 3. 排序取前N │ │ ↓ ↓ [选择技能] ──→ [调用工具] │ │ ↓ ↓ spatial-query spatial_helper.py │ │ └───────┬───────┘ ↓ [整合结果] ↓ [返回用户] ``` ### 关键概念验证 | 概念 | 实践体现 | |-----|---------| | Agent | Claude Code作为智能体,理解意图并协调执行 | | Skill | spatial-query技能封装了空间分析能力 | | Tool | spatial_helper.py是具体实现工具 | --- ## 反思问题 1. **理解验证**:你能在脑海中复述一遍AI执行这个任务的流程吗? 2. **扩展思考**:如果要让这个助手支持更多空间操作,应该如何设计? 3. **局限性**:当前实现有哪些不足?如何改进? 4. **迁移应用**:这个模式可以应用到你的专业领域吗? --- ## 下一步 完成这个实践后,你已经: - ✅ 配置了Claude Code环境 - ✅ 创建了第一个空间分析技能 - ✅ 理解了Agent的基本工作方式 准备好进入下一章:**01-foundations(基础原理)**