dtcc代理
LLM代理接口 DTCC平台. 展示城市数字孪生模拟 主控程序 工具,使Claude和其他LLM代理能够发现数据集,检查城市 上下文,运行环境模拟,并通过自然方法解释结果 语言。
建筑
LLM (Claude) ←→ MCP protocol ←→ dtcc-agent
├── geocode (pyproj + Nominatim)
├── get_buildings (dtcc_core.datasets)
├── run_simulation (dtcc-sim remote or in-process)
├── compare_scenarios (composes the above)
├── list_operations ─┐
├── describe_operation │ dynamic dispatch
├── run_operation │ (109 operations)
├── list_objects │ with object store
├── inspect_object │
├── delete_object │
├── get_field_names │
├── export_object │
├── object_to_text │
├── spatial_query ─┘
├── render_object (dtcc_viewer, offscreen)
└── disk_cache (spatial containment, TTL eviction)dtcc代理可以在两种模式下运行:
- 迷你服务模式:Lurkie和MCP服务器在轻量级中运行
Python容器。模拟工具调用 dtcc-sim 迷你服务通过 相同的 dtcc-core Atlas使用的远程数据集协议。
- 直接模式:MCP服务器导入
dtcc_core和dtcc_sim直接
正在进行中。这需要一个完整的科学环境。
先决条件
对于Docker mini服务,您需要:
- 码头工人
- 跑步
dtcc-sim迷你服务 - 克劳德·奥斯特,要么
CLAUDE_CODE_OAUTH_TOKEN或ANTHROPIC_API_KEY
对于直接进程内使用,dtcc代理在与以下相同的环境中运行 dtcc sim。您需要:
- FEniCSx(dolfinx)通过conda
- dtcc核心和dtcc(pip)
- dtcc-sim(pip)
- dtcc-tetgen包装器(来源)
请参阅 dtcc-sim README 有关环境设置说明。
安装
pip install -e .对于网络聊天机器人附加功能:
pip install -e ".[chatbot]"用法
使用克劳德桌面/克劳德代码
添加到MCP配置(.mcp.json 或克劳德桌面设置):
{
"mcpServers": {
"dtcc-agent": {
"command": "python",
"args": ["-m", "dtcc_agent"]
}
}
}独立
python -m dtcc_agentDocker迷你服务
开始 dtcc-sim 首先,构建并运行代理服务:
cd ../dtcc-sim
docker compose up -d
cd ../dtcc-agent
mkdir -p data/agent
export DTCC_REMOTE_SERVICES=http://host.docker.internal:8001
export CLAUDE_CODE_OAUTH_TOKEN=...
docker compose up --build在macOS上,挂载 ~/.claude 对于本地Claude身份验证来说,进入Docker是不够的: Claude Code将OAuth凭据存储在Keychain中。生成容器令牌 在主机上并将其传递到环境中:
claude setup-token
export CLAUDE_CODE_OAUTH_TOKEN="sk-ant-oat01-PASTE-TOKEN-HERE"不要包裹 claude setup-token 在命令替换中。它是互动的 可以将整个登录屏幕捕获到 CLAUDE_CODE_OAUTH_TOKEN,这使得 克劳德发送了一个无效 Authorization: Bearer ... 头球验证无 打印令牌:
python verify_auth.py --require-oauth启动Docker后,验证令牌是否到达容器:
docker compose exec -T dtcc-agent python verify_auth.py --require-oauthANTHROPIC_API_KEY 如果您更喜欢API-key身份验证,则也支持。
服务正在监听http://localhost:8050并在以下位置公开健康端点 http://localhost:8050/health.
Docker布局镜像 dtcc-sim:
Dockerfiledocker-compose.ymlbuild_docker.sh
可用工具
仿真工具(硬编码)
| 工具 | 说明 |
|---|---|
geocode | 将地名转换为EPSG:3006边界框 |
get_buildings | 检查边界框中的建筑物 |
list_simulations | 发现可用的模拟类型 |
get_simulation_schema | 获取模拟的参数模式 |
run_simulation | 运行模拟并返回摘要统计信息 |
compare_scenarios | 运行两个模拟并比较结果 |
list_past_runs | 列出最近的模拟运行 |
get_run_summary | 重新检查过去的模拟结果 |
动态调度工具(109次操作)
| 工具 | 说明 |
|---|---|
list_operations | 浏览dtcc核心业务的完整目录 |
describe_operation | 获取任何操作的参数架构 |
run_operation | 执行任何操作并存储结果 |
list_objects | 列出内存存储中的对象 |
inspect_object | 获取存储对象的详细摘要 |
delete_object | 删除存储的对象并释放内存 |
get_field_names | 发现附加到存储对象的字段/数据 |
export_object | 将对象导出到文件(CSV、OBJ、PLY、STL、VTK、glTF等) |
object_to_text | 获取存储对象的丰富markdown表示 |
spatial_query | 空间过滤、最近站查找、基于高度的查询 |
可视化工具
| 工具 | 说明 |
|---|---|
render_object | 将存储的对象渲染为PNG屏幕截图(通过dtcc查看器进行屏幕外3D) |
动态调度工具公开 全部 dtcc核心:
| 类别 | 计数 | 示例 |
|---|---|---|
builder | 73 | 地形光栅、曲面网格、建筑高度、树木检测、点云过滤器 |
io | 18 | 加载/保存点云、网格、光栅、城市;下载数据 |
datasets | 12 | 点云、建筑物、地形、树木、天气、模拟 |
reproject | 6 | 在CRS之间重新投影点云、网格、曲面 |
运作原理
对象存储和管道
结果来自 run_operation 以短8个字符存储在内存中 十六进制ID。您将这些ID作为参数传递给后续操作, 建造多级管道:
run_operation("datasets.point_cloud", {"bounds": [...]})
→ result_id: "a1b2c3d4" (PointCloud stored in memory)
run_operation("builder.build_terrain_raster", {"pc": "a1b2c3d4", "cell_size": 2.0})
→ result_id: "e5f6g7h8" (Raster stored, built from the point cloud)标记的参数 is_object_ref: true 在 describe_operation 输出 接受这些ID。调度员会自动从商店中解析它们。
商店使用LRU驱逐(默认限制为2GB)来防止无限制 长时间会话期间的记忆增长。
什么会被退回
run_operation 从不返回原始数组数据。相反,它会返回 特定类型的摘要:
- 点云:num_points、界限、分类计数、z-stats
- 网格:num_vertices、num_faces、界限、标记信息
- 光栅:形状、单元格大小、边界、值统计(min/max/mean/std)
- 城市:num_buildings,has_terrain,高度统计
- 元组:每个元素都用链接的ID单独存储
使用 inspect_object(id) 以获取任何存储对象的详细摘要。
磁盘缓存
昂贵的操作(数据集下载、构建器计算)是 自动缓存到磁盘 /tmp/dtcc_cache/。缓存使用:
- 空间遏制 对于数据集:如果缓存的结果覆盖了
大于请求的区域,缓存的数据将被重用和裁剪。
- 内容指纹识别 对于构建器:输入对象按以下方式散列
它们的元数据(类型、大小、来源),因此与 即使在会话之间,等效的输入也会命中缓存。
- TTL驱逐 (7天)和a 磁盘预算 (10 GB),带
最古老的第一次驱逐。
两者 run_operation (通过调度员)和 get_buildings (直接 MCP工具)在从外部源获取之前检查磁盘缓存。
示例
示例1:热浪影响分析
User: "How does a heatwave affect Lindholmen in Gothenburg?"
Agent calls: geocode("Lindholmen")
→ bounds [318866, 6399800, 319366, 6400300] in EPSG:3006
Agent calls: get_buildings(bounds)
→ 47 buildings, 3–45m height
Agent calls: compare_scenarios("urban_heat_simulation", bounds,
{air_temperature: 20}, {air_temperature: 38})
→ baseline mean 17.8°C, heatwave mean 36.2°C, max 47.1°C
Agent: "Temperature increases by 18.4°C on average, with dangerous
peaks of 47.1°C in street canyons..."示例2:地形分析管道
下载点云,构建地形光栅,然后计算坡度:
User: "Analyze the terrain slope around Chalmers"
Agent calls: geocode("Chalmers")
→ bounds [319700, 6399500, 320200, 6400000]
Agent calls: list_operations(search="terrain")
→ shows datasets.point_cloud, builder.build_terrain_raster,
builder.raster.slope_aspect, ...
Agent calls: run_operation("datasets.point_cloud",
{"bounds": [319700, 6399500, 320200, 6400000]})
→ result_id: "a1b2c3d4", summary: 1.2M points, z range 5–48m
Agent calls: run_operation("builder.build_terrain_raster",
{"pc": "a1b2c3d4", "cell_size": 2.0})
→ result_id: "e5f6g7h8", summary: 250×250 raster, elevation 5–48m
Agent calls: run_operation("builder.raster.slope_aspect",
{"dem": "e5f6g7h8"})
→ result_ids: ["f9g0h1i2", "j3k4l5m6"] (slope + aspect rasters)
Agent calls: inspect_object("f9g0h1i2")
→ slope raster: mean 0.12 rad (7°), max 0.8 rad (46°)
Agent: "The terrain around Chalmers is mostly gentle (mean slope 7°)
with some steep sections reaching 46° near the hillside..."示例3:建筑物和树木清单
User: "What buildings and trees are in Lindholmen?"
Agent calls: geocode("Lindholmen")
→ bounds [318866, 6399800, 319366, 6400300]
Agent calls: run_operation("datasets.buildings",
{"bounds": [318866, 6399800, 319366, 6400300]})
→ result_id: "b1c2d3e4", 47 buildings, heights 3–45m
Agent calls: run_operation("datasets.point_cloud",
{"bounds": [318866, 6399800, 319366, 6400300]})
→ result_id: "f5g6h7i8"
Agent calls: run_operation("builder.trees_from_pointcloud",
{"pc": "f5g6h7i8"})
→ result_id: "j9k0l1m2", 128 trees, height 4–18m
Agent calls: list_objects()
→ 3 objects, 45 MB total
Agent: "Lindholmen has 47 buildings (3–45m tall) and approximately
128 detected trees (4–18m tall) from the LiDAR data..."示例4:3D建筑可视化
下载某个区域的建筑物并渲染3D屏幕截图:
User: "Show me the buildings in Lindholmen"
Agent calls: geocode("Lindholmen")
→ bounds [318866, 6399800, 319366, 6400300]
Agent calls: run_operation("datasets.buildings",
{"bounds": [318866, 6399800, 319366, 6400300]})
→ result_id: "b1c2d3e4", 47 buildings, heights 3–45m
Agent calls: render_object("b1c2d3e4")
→ {"image_path": "/tmp/dtcc_screenshots_xxx/b1c2d3e4.png",
"type": "City", "width": 1200, "height": 800}
Agent: "Here's a 3D rendering of the 47 buildings in Lindholmen.
The tallest building reaches 45m..."示例5:地形可视化管道
构建地形光栅并渲染它:
User: "Visualize the terrain around Chalmers"
Agent calls: geocode("Chalmers")
→ bounds [319700, 6399500, 320200, 6400000]
Agent calls: run_operation("datasets.point_cloud",
{"bounds": [319700, 6399500, 320200, 6400000]})
→ result_id: "a1b2c3d4", 1.2M points
Agent calls: run_operation("builder.build_terrain_raster",
{"pc": "a1b2c3d4", "cell_size": 2.0})
→ result_id: "e5f6g7h8", 250×250 raster, elevation 5–48m
Agent calls: render_object("e5f6g7h8")
→ {"image_path": "/tmp/dtcc_screenshots_xxx/e5f6g7h8.png",
"type": "Raster", "width": 1200, "height": 800}
Agent: "Here's the terrain raster for the Chalmers area. Elevation
ranges from 5m near the waterfront to 48m on the hillside..."示例6:发现操作
Agent calls: list_operations(category="builder")
→ 73 operations: build_terrain_raster, build_city_surface_mesh,
trees_from_pointcloud, merge_meshes, slope_aspect, ...
Agent calls: describe_operation("builder.build_city_surface_mesh")
→ params: city (object_ref, required), max_mesh_size (float, default 10),
min_mesh_angle (float, default 20.7), ...
Agent calls: describe_operation("builder.pc_filter.remove_vegetation")
→ params: pc (object_ref, required)
→ returns: PointCloud网络聊天机器人(Lurkie)
聊天机器人提供了一个基于浏览器的聊天界面,由Claude Agent SDK提供支持。
安装
pip install -e ".[chatbot]"跑
python -m chatbot然后打开http://localhost:8050在您的浏览器中。日志被写入 /tmp/dtcc_lurkie_logs/.
运作原理
聊天机器人使用Claude Agent SDK作为MCP服务器连接到dtcc代理。 用户消息通过WebSocket发送,Claude的响应(包括工具调用) 以及3D渲染)实时流回。
特征:
- 对话记忆:过去的交易记录存储在ChromaDB和
通过RAG检索以提供跨会话上下文。
- 错误恢复:如果恢复的SDK会话失败(例如上下文
限制),聊天机器人会自动重试新的会话。
- 会话管理:会话将在1小时后过期。“新聊天”
按钮允许用户在不重新加载的情况下重新开始。
- 安全:渲染的markdown用DOMPurify进行消毒,以
防止XSS。
