大语言模型与物理引擎融合:PhyScensis项目实现AI在3D物理世界中的场景布置

📅 发布时间:2026/8/24 8:24:09
大语言模型与物理引擎融合:PhyScensis项目实现AI在3D物理世界中的场景布置 1. 项目概述当大语言模型遇上物理引擎最近在搞一个挺有意思的项目叫 PhyScensis。简单来说它试图解决一个核心问题如何让一个只会“纸上谈兵”的大语言模型LLM真正学会在复杂的3D物理世界里“动手”布置场景这听起来像是科幻电影里的情节但其实是当前AI研究一个非常务实且充满挑战的前沿方向。我们平时用LLM无论是ChatGPT还是Claude让它写首诗、写段代码、做个规划它都能做得有模有样。但如果你让它去布置一个房间比如“把沙发、茶几、电视柜合理地摆放在这个客厅里确保人能顺畅走动电视正对沙发并且茶几在沙发伸手可及的位置”它给出的文字描述可能很完美但一旦放到一个真实的、有重力、有碰撞、有摩擦力的3D物理环境中这个方案很可能根本无法实现——沙发可能会穿墙而过茶几可能因为重心不稳而倾倒或者电视柜挡住了门。PhyScensis 就是为了弥合这个“认知鸿沟”而生的。它的核心思想是“物理增强”Physics-Augmented即给LLM这个“大脑”配上一个“物理身体”——一个物理引擎如PyBullet, MuJoCo, NVIDIA PhysX。LLM负责高层的任务理解、规划和常识推理而物理引擎则负责验证每一个动作在物理世界中的可行性并提供真实的物理反馈如碰撞检测、刚体动力学模拟。通过这种“脑体协同”的方式构建出的智能体Agent就能在复杂的3D场景中完成从“想”到“做”的闭环。这个项目对于机器人任务规划、游戏内容自动生成、虚拟环境搭建、甚至数字孪生中的场景初始化都有着巨大的潜在价值。它不只是让AI“说”得对更要让它“做”得对。2. 核心架构与工作流程拆解PhyScensis 不是一个单一的工具而是一个融合了多种技术的智能体框架。要理解它我们需要拆解其核心的工作流程这通常是一个“感知-规划-执行-验证”的循环。2.1 系统核心组件交互整个系统的运行依赖于几个关键组件的紧密配合大语言模型LLM担任“指挥官”和“策划师”的角色。它接收自然语言指令如“布置一个温馨的读书角”并利用其庞大的知识库进行任务分解、物体关系推理和初步的动作序列生成。例如它会知道读书角需要书架、单人沙发、落地灯、小边几等元素并理解这些物体之间应有的空间关系灯在沙发旁边书架在沙发背后或侧面。物理引擎Physics Engine担任“物理世界模拟器”和“动作验证器”的角色。它维护着一个精确的3D物理环境其中所有物体都有质量、形状、摩擦系数、碰撞体积等物理属性。当LLM提出一个动作如“将沙发移动到坐标(x, y, z)”物理引擎会模拟执行这个动作并返回结果是否发生了碰撞物体是否稳定放置是否需要施加额外的力场景解析与物体库Scene Parser Object Library这是连接抽象指令和具体实物的桥梁。系统需要有一个丰富的3D模型库包含沙发、桌子、杯子等各种物体的网格模型及物理属性并能根据LLM的描述从库中检索并实例化正确的物体到物理引擎中。同时它也需要能解析初始的空白场景或已有场景的3D结构。反馈循环机制Feedback Loop这是PhyScensis 智能的核心。物理引擎的验证结果成功、失败及失败原因会被格式化成一个简明的文本或结构化数据反馈给LLM。LLM根据这个反馈调整它的下一步计划。例如如果物理引擎反馈“移动沙发失败与墙壁发生碰撞”LLM就会重新规划一条无碰撞的移动路径。2.2 典型工作流程步骤一个完整的 PhyScensis 任务执行流程可以概括为以下步骤任务输入与解析用户输入自然语言指令。LLM首先解析指令明确最终目标、约束条件如预算、风格、物理限制和隐含的常识要求。场景初始化与物体选取根据指令系统从3D物体库中选取合适的模型并将其以合理的初始姿态通常是随机但无碰撞的位置放入物理引擎构建的空白场景或指定场景中。分层任务规划LLM将宏观任务分解为一系列可执行的原子动作例如“抓取物体A”、“移动至位置B”、“旋转至角度C”、“释放物体”。这个规划过程会考虑物体间的功能关系和空间关系。动作执行与物理模拟规划好的原子动作被转换为物理引擎可理解的API调用如设置目标位置、施加力/扭矩。物理引擎以微小的时间步长推进模拟计算物体的运动轨迹、碰撞反应等。观察与状态评估在每个动作或一系列动作后系统从物理引擎中“观察”场景的新状态物体的位置、姿态、是否稳定、是否发生非预期碰撞等。反馈生成与策略调整将观察到的状态尤其是失败信息转化为自然语言描述反馈给LLM。LLM分析失败原因并重新规划后续动作。例如如果书放不到倾斜的书架上滑落了LLM可能会决定先扶正书架或者换一个更平坦的位置放书。循环迭代直至完成重复步骤4-6直到LLM判断任务目标已达成或经过多轮尝试后仍无法解决此时可能需要人工干预或返回失败。这个过程的关键在于LLM并不是一次性生成一个完美的、冗长的动作序列而是在物理引擎的实时“辅导”下进行“小步快跑快速迭代”这与人类在陌生环境中摸索完成任务的方式非常相似。3. 关键技术难点与解决方案将LLM与物理引擎结合听起来很美好但在工程和算法层面面临着诸多挑战。PhyScensis 这类项目的价值很大程度上体现在如何巧妙地解决这些难点上。3.1 自然语言到物理动作的“语义鸿沟”这是最根本的挑战。LLM输出的是文本而物理引擎需要的是精确的数值参数坐标、欧拉角、力的大小。如何把“把沙发往窗边挪一点”这种模糊的指令转化成“对沙发模型施加一个沿向量(2, 0, 0)的力持续1.5秒”这样的具体操作解决方案与实操要点定义原子动作API首先需要为智能体设计一套有限的、高层次的“原子动作”指令集。这套指令集是LLM和物理引擎之间的“协议”。例如pick_up(object_id)place_at(object_id, x, y, z)move_to(object_id, target_x, target_y, target_z)rotate(object_id, axis, degrees)push(object_id, direction_vector)scan_environment()- 返回场景中所有物体的位置和状态描述。 这样LLM只需要学会调用这些API并填充参数而不是直接控制底层物理。参数化与常识嵌入对于“挪一点”这样的模糊词需要将其参数化。这可以通过以下方式实现规则映射预先定义“一点”“0.5米”“旁边”“距离0.3米以内”。这种方式简单但死板。LLM自身估算在上下文中让LLM根据物体尺寸进行估算。例如提问LLM“一个标准三人沙发宽度大约2米‘挪一点’在布置房间时通常指移动多少距离请给出一个合理的数值估计。”然后将这个估计值填入API。学习型映射高级收集人机交互数据训练一个专门的模型来将模糊空间语言映射为具体数值范围。注意在项目初期建议采用“规则映射 LLM估算”的混合策略。为常用空间关系词如“附近”、“正对”、“紧挨着”制定一套默认规则同时允许LLM在特定场景下覆盖这些规则。这能在保证基础可用的前提下引入一定的灵活性。3.2 物理仿真的效率与真实性平衡物理模拟是非常计算密集的。高精度、高频率的模拟小时间步长、复杂的碰撞检测虽然真实但速度慢无法支撑智能体的快速试错学习。反之过于简化的模拟又会导致“模拟器与现实之间的差距”Sim2Real Gap学到的策略在真实世界无效。解决方案与实操要点分层仿真策略快速规划层在LLM进行初始宏观规划时使用一个极度简化的“轻量级物理模型”。例如将物体视为忽略形状的质点仅进行粗略的碰撞检测AABB包围盒。这一步的目的是快速排除明显不合理的方案比如把沙发放在房间正中央挡住所有通道。精细验证层当LLM输出一个具体的动作序列后再调用高精度物理引擎对该序列进行“慢速回放”验证。使用更小的仿真步长、精确的网格碰撞检测和复杂的关节动力学。只有通过这层验证的动作序列才会被最终确认。这种“先粗后细”的策略能极大提高整体规划效率。动作抽象与子目标分解不要让LLM去规划每一个微小的关节运动。相反让LLM规划子目标状态如“杯子在桌面上”而由一个底层的、传统的机器人控制器如逆运动学IK求解器、路径规划器来负责生成具体的关节轨迹。这个控制器可以利用物理引擎进行内部的、高效的轨迹优化。这样LLM只需要关心“做什么”而把“怎么做”交给更专业的底层模块。3.3 长期规划与信用分配问题布置一个复杂场景需要一系列动作。如果最终失败了LLM很难知道是哪个早期动作导致了失败信用分配问题。此外LLM的上下文长度有限难以在单个提示中规划和跟踪一个非常长的动作序列。解决方案与实操要点递归任务分解ReAct模式增强强制LLM以“思考-行动-观察”的循环模式工作。在每一个循环中LLM只规划当前最急需的1-3个动作然后立即执行并观察结果。这相当于将长期规划分解为连续的短期规划。在提示词Prompt中需要明确要求LLM输出Thought:、Action:和Action Input:的结构化内容。维持外部状态记忆由于LLM本身是“无状态”的需要为智能体维护一个外部的“工作记忆”。这个记忆可以记录已完成的子目标、当前场景的状态摘要、尝试过但失败的动作及其原因。在每一轮循环中将这份记忆和最新的观察一起作为上下文输入给LLM帮助它做出更连贯的决策。利用物理引擎提供密集奖励对于训练型的智能体而非纯规划可以设计基于物理状态的奖励函数。例如物体放置的稳定性接触点数量、重心投影、场景的美观度基于规则的评分、任务完成度目标物体是否在指定区域。这些密集的奖励信号可以帮助学习算法更好地进行信用分配。4. 从零搭建一个简易PhyScensis原型理解了原理和难点后我们可以尝试动手搭建一个极度简化的原型来体验这个工作流程。这里我们选择 Python 作为开发语言使用 OpenAI GPT API 作为 LLMPyBullet 作为物理引擎。4.1 环境准备与依赖安装首先创建一个新的Python虚拟环境并安装核心库。# 创建并激活虚拟环境可选但推荐 python -m venv physcensis_env source physcensis_env/bin/activate # Linux/Mac # physcensis_env\Scripts\activate # Windows # 安装核心依赖 pip install openai # 用于调用GPT API pip install pybullet # 物理引擎 pip install numpy # 数值计算 pip install transforms3d # 用于处理3D旋转可选但方便确保你有一个可用的 OpenAI API 密钥并将其设置为环境变量export OPENAI_API_KEYyour-api-key-here # Linux/Mac # set OPENAI_API_KEYyour-api-key-here # Windows4.2 构建基础框架场景与物体我们创建一个简单的脚本初始化一个PyBullet物理场景并加载几个基本的3D物体立方体、球体作为我们的“家具”。import pybullet as p import pybullet_data import time import numpy as np class SimplePhysicsScene: def __init__(self, guiTrue): 初始化物理场景 if gui: self.physicsClient p.connect(p.GUI) # 开启图形界面 else: self.physicsClient p.connect(p.DIRECT) # 无界面更快 p.setAdditionalSearchPath(pybullet_data.getDataPath()) p.setGravity(0, 0, -9.8) # 设置重力 # 加载地面 self.ground_id p.loadURDF(plane.urdf) # 一个简单的物体库用形状和颜色代表不同物体 self.object_lib { table: {shape: p.GEOM_BOX, dimensions: [0.6, 0.6, 0.05], color: [0.7, 0.5, 0.3, 1]}, cup: {shape: p.GEOM_CYLINDER, dimensions: [0.05, 0.1], color: [0.2, 0.6, 0.9, 1]}, book: {shape: p.GEOM_BOX, dimensions: [0.2, 0.15, 0.02], color: [0.9, 0.2, 0.2, 1]}, } self.objects {} # 存储场景中物体ID的字典格式{obj_name: body_id} def add_object(self, obj_type, pos, ornNone): 向场景中添加一个物体 if obj_type not in self.object_lib: print(f未知物体类型: {obj_type}) return None info self.object_lib[obj_type] if orn is None: orn p.getQuaternionFromEuler([0,0,0]) if info[shape] p.GEOM_BOX: col_id p.createCollisionShape(info[shape], halfExtents[d/2 for d in info[dimensions]]) vis_id p.createVisualShape(info[shape], halfExtents[d/2 for d in info[dimensions]], rgbaColorinfo[color]) elif info[shape] p.GEOM_CYLINDER: col_id p.createCollisionShape(info[shape], radiusinfo[dimensions][0], heightinfo[dimensions][1]) vis_id p.createVisualShape(info[shape], radiusinfo[dimensions][0], lengthinfo[dimensions][1], rgbaColorinfo[color]) else: # 其他形状... return None body_id p.createMultiBody(baseMass1.0, baseCollisionShapeIndexcol_id, baseVisualShapeIndexvis_id, basePositionpos, baseOrientationorn) self.objects[obj_type] body_id return body_id def get_scene_state(self): 获取当前场景的状态描述用于反馈给LLM state_desc 当前场景中有以下物体\n for name, body_id in self.objects.items(): pos, orn p.getBasePositionAndOrientation(body_id) # 简单判断是否稳定检查线速度和角速度是否接近零 lin_vel, ang_vel p.getBaseVelocity(body_id) speed np.linalg.norm(lin_vel) np.linalg.norm(ang_vel) is_stable 稳定 if speed 0.01 else 不稳定正在运动 state_desc f- {name}: 位置{np.round(pos,2)}, 状态{is_stable}\n # 检查关键关系简易版例如书是否在桌子上方很近的地方 if table in self.objects and book in self.objects: t_pos, _ p.getBasePositionAndOrientation(self.objects[table]) b_pos, _ p.getBasePositionAndOrientation(self.objects[book]) # 简单检查垂直距离和水平距离 vert_dist abs(t_pos[2] - b_pos[2]) horiz_dist np.linalg.norm(np.array(t_pos[:2]) - np.array(b_pos[:2])) if vert_dist 0.2 and horiz_dist 0.4: # 阈值需要根据物体尺寸调整 state_desc 观察书目前在桌子附近。\n else: state_desc 观察书不在桌子附近。\n return state_desc def run_simulation(self, steps100): 运行物理仿真若干步 for _ in range(steps): p.stepSimulation() if self.physicsClient 0: # 如果是GUI模式稍微延迟以便观察 time.sleep(1./240.) def close(self): p.disconnect() # 测试场景 if __name__ __main__: scene SimplePhysicsScene(guiTrue) scene.add_object(table, pos[0, 0, 0]) scene.add_object(cup, pos[0.2, 0, 0.3]) # 杯子悬空 scene.add_object(book, pos[0, 0.5, 0.5]) # 书悬空 scene.run_simulation(500) # 让物体自由落体 print(scene.get_scene_state()) input(按回车退出...) scene.close()运行这个脚本你会看到一个图形窗口桌子、杯子和书会落下杯子可能会从桌上弹开。get_scene_state函数会生成一段文本描述这就是我们反馈给LLM的“观察”。4.3 集成LLM构建ReAct智能体循环现在我们创建智能体的核心循环。它将接收用户指令调用LLM执行LLM建议的动作并观察结果。import openai import json import re class SimplePhyscensisAgent: def __init__(self, scene, llm_modelgpt-4): self.scene scene self.llm_model llm_model self.memory [] # 记录交互历史 # 定义智能体可以执行的动作列表我们的API self.actions { MOVE_TO: 将指定物体移动到目标位置。参数object_name, target_x, target_y, target_z, PLACE_ON: 将一个物体放置在另一个物体的顶部近似。参数object_to_move, base_object, SCAN: 扫描当前场景状态无参数。, DONE: 任务完成无参数。 } def call_llm(self, prompt): 调用OpenAI API try: response openai.ChatCompletion.create( modelself.llm_model, messages[{role: user, content: prompt}], temperature0.1, # 低温度保证输出稳定 max_tokens500 ) return response.choices[0].message.content.strip() except Exception as e: print(f调用LLM API失败: {e}) return None def parse_llm_action(self, llm_response): 解析LLM的回复提取动作和参数。 期望格式THOUGHT: ... ACTION: MOVE_TO PARAMS: {object_name:book, target_x:0, target_y:0, target_z:0.3} # 简单的正则表达式匹配 action_pattern rACTION:\s*(\w) params_pattern rPARAMS:\s*(\{.*?\}) action_match re.search(action_pattern, llm_response, re.IGNORECASE) params_match re.search(params_pattern, llm_response, re.DOTALL) action action_match.group(1) if action_match else None params_str params_match.group(1) if params_match else {} try: params json.loads(params_str) except json.JSONDecodeError: params {} return action, params def execute_action(self, action_name, params): 在物理场景中执行解析出的动作 if action_name SCAN: return self.scene.get_scene_state() elif action_name MOVE_TO: obj_name params.get(object_name) target_pos [params.get(target_x, 0), params.get(target_y, 0), params.get(target_z, 0)] if obj_name in self.scene.objects: body_id self.scene.objects[obj_name] # 在物理引擎中直接设置位置瞬移。更真实的做法是施加力。 p.resetBasePositionAndOrientation(body_id, target_pos, [0,0,0,1]) self.scene.run_simulation(50) # 运行几步模拟让物体稳定 return f已尝试将 {obj_name} 移动到位置 {target_pos}。 else: return f错误场景中不存在物体 {obj_name}。 elif action_name PLACE_ON: obj_name params.get(object_to_move) base_name params.get(base_object) if obj_name in self.scene.objects and base_name in self.scene.objects: obj_id self.scene.objects[obj_name] base_id self.scene.objects[base_name] base_pos, _ p.getBasePositionAndOrientation(base_id) # 简单计算放置位置在基础物体的正上方 # 这里需要根据物体尺寸精细计算此处简化处理 target_pos [base_pos[0], base_pos[1], base_pos[2] 0.2] p.resetBasePositionAndOrientation(obj_id, target_pos, [0,0,0,1]) self.scene.run_simulation(100) # 多运行几步看是否稳定 obs self.scene.get_scene_state() return f已尝试将 {obj_name} 放置在 {base_name} 上。观察{obs} else: return f错误物体 {obj_name} 或 {base_name} 不存在。 elif action_name DONE: return 任务完成。 else: return f错误未知动作 {action_name}。 def run_task(self, user_instruction, max_steps10): 运行主任务循环 print(f用户指令{user_instruction}) print(*50) # 初始观察 current_obs self.scene.get_scene_state() self.memory.append(f初始状态{current_obs}) for step in range(max_steps): print(f\n--- 步骤 {step1} ---) # 构建给LLM的提示词 prompt f 你是一个在物理模拟环境中操作的机器人。你的目标是{user_instruction} 你可以执行以下动作 {json.dumps(self.actions, indent2, ensure_asciiFalse)} 当前场景观察 {current_obs} 之前的操作历史 {chr(10).join(self.memory[-3:]) if self.memory else 无} 请按照以下格式思考并回应 THOUGHT: 首先分析当前情况和目标决定下一步做什么。 ACTION: 从可用动作中选择一个动作名称。 PARAMS: 以JSON格式提供动作所需的参数。 例如 THOUGHT: 书目前在空中。我需要把它放到桌子上。桌子是稳定的。我应该使用PLACE_ON动作。 ACTION: PLACE_ON PARAMS: {{object_to_move: book, base_object: table}} print(f提示词发送给LLM...) llm_response self.call_llm(prompt) if not llm_response: print(LLM无响应退出。) break print(fLLM回复\n{llm_response}) # 解析并执行动作 action, params self.parse_llm_action(llm_response) print(f解析结果 - 动作{action}, 参数{params}) if action DONE: print(智能体认为任务已完成。) break if action: result self.execute_action(action, params) print(f动作执行结果{result}) # 更新观察 current_obs self.scene.get_scene_state() # 记录到记忆 self.memory.append(f步骤{step1}: 执行 {action}结果{result}) self.memory.append(f步骤{step1}后观察{current_obs}) else: print(未能从LLM回复中解析出有效动作。) break print(\n *50) print(任务循环结束。最终场景状态) print(current_obs) # 主程序 if __name__ __main__: # 初始化场景 scene SimplePhysicsScene(guiTrue) scene.add_object(table, pos[0, 0, 0]) scene.add_object(book, pos[0, 0.5, 1.0]) # 书初始在高处 scene.run_simulation(200) # 让物体落下稳定 # 创建智能体 agent SimplePhyscensisAgent(scene, llm_modelgpt-3.5-turbo) # 可用gpt-4以获得更好效果 # 运行任务 user_instruction 请把书放到桌子上。 agent.run_task(user_instruction, max_steps5) input(按回车退出...) scene.close()这个原型虽然简单但完整展示了 PhyScensis 的核心思想LLM根据目标和观察进行思考生成动作指令物理引擎执行并反馈结果智能体根据结果进行下一步决策。5. 常见问题、优化方向与避坑指南在实际开发和应用中你会遇到比上述原型复杂得多的问题。以下是一些常见挑战和进阶优化思路。5.1 提示工程Prompt Engineering的稳定性LLM的输出并不总是稳定可控的。它可能不遵循你规定的输出格式或者做出不符合物理常识的决策。避坑技巧与优化方案结构化输出强制在提示词中严格要求JSON或特定格式输出并可以在代码中添加后处理逻辑。如果LLM输出格式错误可以将其格式错误信息连同原提示再次发送给LLM要求它纠正。一些新的LLM API如OpenAI的JSON Mode、Anthropic的Claude原生支持结构化输出应优先使用。少样本学习Few-shot Learning在提示词中提供2-3个完整的、正确的“观察-思考-行动”示例。这是引导LLM理解任务格式和决策逻辑最有效的方法之一。思维链Chain-of-Thought引导明确要求LLM在输出动作前先输出“THOUGHT”阐述其推理过程。这不仅能让输出更可靠也便于我们调试智能体的决策逻辑。参数范围与常识约束在提示词中明确告知LLM物理世界的约束。例如“注意房间尺寸是5x5米坐标范围是X[-2.5, 2.5], Y[-2.5, 2.5]。物体的质量在1-50千克之间。移动速度不宜过快。”5.2 物理仿真的真实性与效率瓶颈如前所述物理仿真是性能瓶颈。在复杂场景中实时模拟可能慢得无法接受。优化策略并行仿真与提前终止当需要评估多个候选动作时可以并行运行多个物理仿真实例使用p.DIRECT模式。一旦某个仿真出现明显失败如物体飞出场景即可提前终止节省计算资源。学习一个“快速预测器”这是一个更高级的思路。可以收集大量“动作-结果”数据训练一个轻量级的神经网络模型来预测某个动作执行后的粗略结果如成功概率、最终位置范围。这个预测器可以作为一个过滤器在调用重型物理引擎之前快速排除大量坏方案。简化碰撞几何体在物理引擎中使用简单的几何体如立方体、球体、胶囊体来近似复杂的3D网格模型进行碰撞检测可以极大提升性能。渲染时仍然使用高精度网格做到“渲染与碰撞分离”。5.3 场景与物体的语义理解我们的原型中物体是用“table”、“book”这样的标签标识的。但在真实应用中LLM可能需要处理“那个红色的矮脚茶几”、“我昨天买的书”这样的指代。解决方案构建丰富的物体属性数据库每个3D资产不仅要有几何和物理属性还应附带丰富的语义标签名称、类别、颜色、材质、风格、功能、常见摆放位置等。这些属性可以作为元数据供LLM检索和推理。视觉 grounding结合视觉语言模型VLM让智能体能够通过“看”来理解场景。例如先让VLM描述场景图像“画面中央有一张棕色木桌左边有一把蓝色椅子...”然后将这个描述输入给LLM进行规划。这解决了“指代”问题。动态物体管理场景中的物体可能被移动、创建或销毁。需要维护一个动态的物体注册表并实时更新其属性和状态确保LLM拥有最新的场景信息。5.4 从仿真到现实Sim2Real的迁移在仿真中训练或调教好的智能体如何应用到真实的机器人或AR/VR环境中域随机化在仿真训练时随机化物理参数如质量、摩擦系数、物体外观、光照条件等。这能让智能体学会在更广泛的环境条件下工作提高其鲁棒性从而更好地迁移到现实世界。混合现实训练在仿真中规划但关键动作如抓取的成败信号来自真实世界的传感器如力传感器、视觉检测。用真实世界的反馈来修正仿真模型或智能体策略。抽象动作接口保持智能体的“动作API”在仿真和现实中一致。例如pick_up(object_id)这个API在仿真中调用物理引擎的抓取模拟在现实中则触发真实的机器人抓取程序。这样智能体的“大脑”部分可以直接迁移。开发 PhyScensis 这类系统是一个典型的“系统工程”需要自然语言处理、机器人学、计算机图形学和软件工程的交叉知识。从最简单的原型开始逐步迭代针对具体应用场景解决最突出的问题是通往成功最实际的路径。这个领域目前方兴未艾每一个巧妙的解决方案都可能推动智能体更进一步地理解和塑造我们周围的物理世界。