第105章 如何开发 SAI Module
前面几章已经建立了多个 SAI 基础组件:
Individual
Perception
Cognition
Memory
Reasoning
Decision
Behavior
Action
Engine
Adapter
Renderer
Task
Event
State Machine
但是,如果所有功能都直接写进 Individual 或 Kernel,系统会越来越复杂。
因此需要 Module。
本章解决的问题是:
如何把一个相对独立的 SAI 功能封装成 Module,并让系统能够注册、加载、启动、停止和测试它。
核心结构:
Module
↓
Module Interface
↓
Module Class
↓
Registration
↓
Loading
↓
Lifecycle
↓
Testing
1. Module 定义
1.1 Module 是什么
Module 是 SAI 中一个具有明确职责、独立结构和标准生命周期的功能单元。
可以定义为:
Module =
Identity
+
Function
+
Interface
+
Lifecycle
+
Configuration
例如:
PerceptionModule
CognitionModule
MemoryModule
ReasoningModule
DecisionModule
RobotModule
DeviceModule
LearningModule
1.2 Module 的基本特征
一个 Module 至少应该具有:
ID
Name
Version
State
Configuration
Methods
例如:
Module_A
id = perception
name = Perception Module
version = 1.0.0
state = READY
1.3 Module 与其他结构的区别
Module 与 Engine
Module = 功能单元及其生命周期
Engine = 具体功能执行器
一个 Module 可以包含 Engine:
PerceptionModule
↓
PerceptionEngine
Module 与 Extension
Extension = 扩展机制/扩展载体
Module = 系统中的功能单元
一个 Extension 可以携带一个或者多个 Module。
Extension
├── Module_A
├── Module_B
└── Module_C
Module 与 Individual
Individual = SAI 个体运行主体
Module = Individual 可以使用的功能组成
例如:
Individual_A
├── PerceptionModule
├── CognitionModule
├── MemoryModule
├── ReasoningModule
└── DecisionModule
2. Module Interface
2.1 为什么需要 Interface
如果每一个 Module 都采用完全不同的方法:
Module_A.startSystem()
Module_B.runModule()
Module_C.begin()
Module_D.loadNow()
系统就很难统一管理。
因此定义统一 Interface。
2.2 ModuleInterface
interface ModuleInterface
{
public function getId();
public function getName();
public function getVersion();
public function initialize();
public function start();
public function stop();
public function shutdown();
public function getState();
}
这样所有 Module 都必须遵守相同的基本结构。
2.3 Interface 的作用
例如系统拥有:
PerceptionModule
CognitionModule
MemoryModule
ReasoningModule
DecisionModule
ModuleManager 可以统一调用:
$module->initialize();
$module->start();
不需要知道每一个 Module 内部是如何实现的。
2.4 Interface 不定义具体业务
Interface 规定:
有哪些基本方法
但不规定:
Perception 怎么识别
Cognition 怎么理解
Reasoning 怎么计算
Decision 怎么选择
这些属于具体 Module Class。
3. Module Class
3.1 Module Class 定义
Module Class 是 ModuleInterface 的具体实现。
例如开发一个:
PerceptionModule
3.2 PerceptionModule
class PerceptionModule implements ModuleInterface
{
protected $id = 'perception';
protected $name = 'Perception Module';
protected $version = '1.0.0';
protected $state = 'NEW';
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function getVersion()
{
return $this->version;
}
public function initialize()
{
$this->state = 'INITIALIZED';
return true;
}
public function start()
{
if ($this->state !== 'INITIALIZED') {
return false;
}
$this->state = 'RUNNING';
return true;
}
public function stop()
{
$this->state = 'STOPPED';
return true;
}
public function shutdown()
{
$this->state = 'SHUTDOWN';
return true;
}
public function getState()
{
return $this->state;
}
}
3.3 Module Class 的职责
一个 Module Class 可以包含自己的:
Properties
Methods
Engines
Configuration
Dependencies
State
例如:
PerceptionModule
│
├── PerceptionEngine
├── ElementExtractor
├── ObjectRecognizer
└── RelationRecognizer
这样功能就不会全部堆积到 Individual 中。
4. Module Registration
4.1 为什么需要 Registration
系统必须知道:
有哪些 Module
Module 在哪里
Module 使用什么 Class
Module 当前是否启用
Module 有哪些依赖
因此建立 Module Registry。
4.2 Module Registry
例如:
$registry = array(
'perception' => array(
'id' => 'perception',
'name' => 'Perception Module',
'version' => '1.0.0',
'class' => 'PerceptionModule',
'path' => 'modules/PerceptionModule.php',
'enabled' => true,
'state' => 'REGISTERED'
)
);
4.3 Registration 的意义
注册以后:
Module Registry
↓
perception
↓
PerceptionModule
系统知道:
有一个叫 perception 的 Module。
但是:
Registered 不等于 Loaded。
这是非常重要的区别。
5. Module Loading
5.1 Loading 定义
Loading 是把 Registry 中已经注册的 Module Class 加载到运行环境。
流程:
Registry
↓
Read Module
↓
Check File
↓
Load Class
↓
Check Interface
↓
Create Object
↓
Initialize
↓
READY
5.2 File Check
首先检查:
if (!file_exists($path)) {
return false;
}
文件不存在:
Module State = ERROR
而不是假设 Module 已经存在。
5.3 Class Check
加载后检查:
if (!class_exists($className)) {
return false;
}
5.4 Interface Check
还需要检查:
$module = new $className();
if (!($module instanceof ModuleInterface)) {
return false;
}
只有符合 Interface:
ModuleInterface
才能成为标准 Module。
5.5 ModuleManager
可以建立:
class ModuleManager
{
protected $modules = array();
public function register($module)
{
$this->modules[$module->getId()] = $module;
}
public function get($id)
{
if (!isset($this->modules[$id])) {
return null;
}
return $this->modules[$id];
}
public function start($id)
{
$module = $this->get($id);
if (!$module) {
return false;
}
return $module->start();
}
}
6. Module Lifecycle
6.1 生命周期
Module 不应该只有:
ON / OFF
而应该拥有完整生命周期:
NEW
↓
REGISTERED
↓
LOADED
↓
INITIALIZED
↓
READY
↓
RUNNING
↓
STOPPING
↓
STOPPED
↓
SHUTDOWN
6.2 异常状态
还需要:
ERROR
CONFLICT
DISABLED
INVALID
UNKNOWN
例如 Module 文件不存在:
REGISTERED
↓
LOADING
↓
ERROR
而不能进入:
RUNNING
6.3 Module State 与 Individual State
两者不能混淆。
例如:
Individual_A = RUNNING
但是:
LearningModule = STOPPED
这是允许的。
Individual 仍然可以运行,只是当前没有 LearningModule。
如果:
PerceptionModule = ERROR
则 Individual 可以根据系统规则:
暂停
降级
等待
进入错误处理
而不是假设 Perception 仍然可用。
6.4 Module 生命周期事件
Module 状态改变时可以产生 Event:
MODULE_REGISTERED
MODULE_LOADED
MODULE_INITIALIZED
MODULE_STARTED
MODULE_STOPPING
MODULE_STOPPED
MODULE_ERROR
MODULE_SHUTDOWN
这些 Event 可以进入前面的 Event System。
7. Module Testing
7.1 Testing 的目的
Module Testing 不是简单地检查:
文件存在
而是检查 Module 是否能够:
注册
加载
初始化
启动
执行
停止
关闭
7.2 基础测试顺序
1. File Test
2. Class Test
3. Interface Test
4. Construction Test
5. Initialization Test
6. Start Test
7. State Test
8. Function Test
9. Stop Test
10. Shutdown Test
7.3 File Test
if (!file_exists($modulePath)) {
echo 'FILE_ERROR';
}
7.4 Interface Test
$module = new PerceptionModule();
if ($module instanceof ModuleInterface) {
echo 'INTERFACE_OK';
}
7.5 Lifecycle Test
$module->initialize();
if ($module->getState() !== 'INITIALIZED') {
echo 'INITIALIZE_FAILED';
}
$module->start();
if ($module->getState() !== 'RUNNING') {
echo 'START_FAILED';
}
7.6 Stop Test
$module->stop();
if ($module->getState() !== 'STOPPED') {
echo 'STOP_FAILED';
}
7.7 Shutdown Test
$module->shutdown();
if ($module->getState() !== 'SHUTDOWN') {
echo 'SHUTDOWN_FAILED';
}
8. Module 示例
现在开发一个真正简单的:
Temperature Module
它的作用是读取温度信息并形成结构化结果。
8.1 项目结构
temperature-module/
│
├── index.php
│
├── ModuleInterface.php
│
├── TemperatureModule.php
│
└── test.php
8.2 ModuleInterface.php
<?php
interface ModuleInterface
{
public function getId();
public function getName();
public function getVersion();
public function initialize();
public function start();
public function stop();
public function shutdown();
public function getState();
}
8.3 TemperatureModule.php
<?php
require_once 'ModuleInterface.php';
class TemperatureModule implements ModuleInterface
{
protected $id = 'temperature';
protected $name = 'Temperature Module';
protected $version = '1.0.0';
protected $state = 'NEW';
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function getVersion()
{
return $this->version;
}
public function initialize()
{
$this->state = 'INITIALIZED';
return true;
}
public function start()
{
if ($this->state !== 'INITIALIZED') {
return false;
}
$this->state = 'READY';
return true;
}
public function stop()
{
$this->state = 'STOPPED';
return true;
}
public function shutdown()
{
$this->state = 'SHUTDOWN';
return true;
}
public function getState()
{
return $this->state;
}
public function analyze($temperature)
{
if ($this->state !== 'READY') {
return array(
'state' => 'REJECTED',
'reason' => 'MODULE_NOT_READY'
);
}
if ($temperature > 85) {
$level = 'HIGH';
} else {
$level = 'NORMAL';
}
return array(
'module' => $this->id,
'temperature' => $temperature,
'level' => $level,
'state' => 'SUCCESS'
);
}
}
9. 运行 Module
index.php:
<?php
require_once 'TemperatureModule.php';
$module = new TemperatureModule();
echo "Module: ";
echo $module->getName();
echo "\n";
echo "State: ";
echo $module->getState();
echo "\n";
$module->initialize();
echo "State: ";
echo $module->getState();
echo "\n";
$module->start();
echo "State: ";
echo $module->getState();
echo "\n";
$result = $module->analyze(92);
print_r($result);
$module->stop();
echo "State: ";
echo $module->getState();
echo "\n";
$module->shutdown();
echo "State: ";
echo $module->getState();
echo "\n";
执行过程:
NEW
↓
INITIALIZED
↓
READY
↓
analyze(92)
↓
HIGH
↓
STOPPED
↓
SHUTDOWN
结果:
module = temperature
temperature = 92
level = HIGH
state = SUCCESS
10. Module 加入 SAI
现在把 TemperatureModule 放进 Individual。
结构:
Individual_A
│
├── PerceptionModule
├── CognitionModule
├── MemoryModule
├── ReasoningModule
├── DecisionModule
└── TemperatureModule
机器人环境中:
TemperatureSensor_A
↓
Information
↓
TemperatureModule
↓
temperature = 92
↓
Perception
↓
Cognition
这里需要注意:
TemperatureModule 可以是一个功能 Module,但它不应该取代完整 Perception。
例如:
TemperatureModule
=
温度数据处理功能
而:
Perception
=
对环境信息进行感知和结构化
两者层次不同。
11. Module 与 SAI Framework
随着系统继续发展:
SAI Framework
│
├── Kernel
│
├── Container
│
├── Registry
│
├── ModuleManager
│
├── EngineManager
│
├── ExtensionManager
│
├── RendererManager
│
├── AdapterManager
│
└── Individual
ModuleManager 管理:
Module
├── PerceptionModule
├── CognitionModule
├── MemoryModule
├── ReasoningModule
├── DecisionModule
├── BehaviorModule
├── LearningModule
└── RobotModule
12. Module 完整加载流程
一个标准 Module 的加载过程:
Module Registry
↓
读取配置
↓
检查文件
↓
加载 Class
↓
检查 Class
↓
检查 ModuleInterface
↓
检查 Dependencies
↓
创建 Module
↓
initialize()
↓
READY
↓
start()
↓
RUNNING
如果任何关键步骤失败:
ERROR
进入:
Detection
↓
Diagnosis
↓
Repair
↓
Verification
这就与前面第72~75章的自我维护体系连接起来。
13. Module 测试与 Verification
Module Testing 最终应该形成结构化结果:
$testResult = array(
'module' => 'temperature',
'file' => 'PASS',
'class' => 'PASS',
'interface' => 'PASS',
'initialize' => 'PASS',
'start' => 'PASS',
'function' => 'PASS',
'stop' => 'PASS',
'shutdown' => 'PASS',
'state' => 'VERIFIED'
);
这里特别区分:
Test Passed
和:
Module Function Verified
测试通过只是测试条件成立。
如果 Module 的实际业务目标是:
temperature = 92
正确结果应该是:
level = HIGH
那么还应该进行业务结果验证。
本章核心模型
SAI Module 可以定义为:
一个具有明确功能边界、统一接口、独立生命周期、可注册、可加载、可测试和可管理的 SAI 功能单元。
完整结构:
SAI Module
│
┌─────────┴─────────┐
↓ ↓
Interface Class
│ │
└─────────┬─────────┘
↓
Registration
↓
Loading
↓
Initialization
↓
READY
↓
RUNNING
↓
STOPPING
↓
STOPPED
↓
SHUTDOWN
异常路径:
Loading / Initialize / Start
↓
ERROR
↓
Detection
↓
Diagnosis
↓
Repair
↓
Verification
↓
READY/RUNNING
Module、Engine、Extension、Manager、Registry 的最终关系
SAI Framework
│
├── Registry
│ └── 记录有哪些 Module
│
├── Manager
│ └── 管理 Module
│
├── Module
│ └── 功能单元
│
├── Engine
│ └── 具体功能执行
│
└── Extension
└── 扩展载体
可以进一步形成:
Extension
↓
Module
↓
Engine
↓
具体功能
但它们不是同一个概念。
最终区别:
Registry = 记录有什么
Manager = 管理什么
Extension = 扩展什么
Module = 功能单元是什么
Engine = 具体怎么执行
Lifecycle = 当前处于什么阶段
Testing = 是否符合预期
Verification= 实际是否得到确认
因此,第105章建立了 SAI 从“功能组件”向“可组织、可加载、可管理功能模块体系”发展的基础。
最终形成:
SAI
│
├── Kernel
│
├── Individual
│
├── Module
│ ├── Perception
│ ├── Cognition
│ ├── Memory
│ ├── Reasoning
│ ├── Decision
│ ├── Behavior
│ └── Learning
│
├── Engine
├── Adapter
├── Renderer
├── Extension
├── Event
├── Task
└── State Machine
这为后续进一步建立模块依赖、模块通信、模块权限、模块配置以及模块自维护提供了基础。