MxJSON 代码审查与执行流程

智能业务描述语言及运行时系统 V1.0 - 完整技术文档

📊 代码评分: 92/100 ✅ 前端API完整 ⚙️ 后端架构优秀 🔒 安全可优化

📑 目录导航

代码质量评估

总体评价:优秀 (92/100)

你的代码架构设计非常优秀,模块划分清晰,功能完整度高。前端TypeScript类型定义完善,后端PHP代码结构规范,已达到生产级别。

📊 各模块评分

模块 评分 亮点 可优化
前端API层 ⭐⭐⭐⭐⭐ 98分 类型定义完整、辅助方法丰富、格式化函数实用 可增加请求重试
协议解析器 ⭐⭐⭐⭐⭐ 95分 完整Schema验证、DFS循环检测、变量引用验证 可增加更多JSON Schema关键字
工作流引擎 ⭐⭐⭐⭐⭐ 94分 支持Sequential/Parallel/DAG三种模式 可增加断点续跑
变量插值引擎 ⭐⭐⭐⭐⭐ 93分 支持嵌套路径、数组索引、13种过滤器 可增加更多内置函数
步骤执行器 ⭐⭐⭐⭐⭐ 92分 支持16种步骤类型、条件判断完善 -
计费引擎 ⭐⭐⭐⭐ 90分 支持8种计费模式、分账功能完善 可增加账单对账
审计日志 ⭐⭐⭐⭐⭐ 92分 多级别日志、智能脱敏、双重存储 可增加日志聚合
UI渲染器 ⭐⭐⭐⭐ 88分 支持26种组件、HTML/JSON/Vue三种格式 Vue组件可增强
安全沙箱 ⭐⭐⭐⭐ 85分 危险函数检测、代码包装执行 建议独立进程执行
MXP加载器 ⭐⭐⭐⭐⭐ 90分 完整ZIP解压、结构验证、国际化支持 -

✨ 代码亮点

设计亮点
  • 完整的TypeScript类型系统 - 前端类型定义覆盖所有接口,IDE智能提示完美
  • DFS循环依赖检测 - 优雅处理DAG工作流的循环依赖问题
  • 智能脱敏机制 - 递归处理嵌套数据,支持多种敏感字段自动掩码
  • 过滤器管道语法 - 支持 {{variable|filter(args)}} 链式处理
  • 条件表达式引擎 - 支持contains/starts_with/in/empty等12种运算符
  • 阶梯计费算法 - 精确的分段累计计算
  • 前端辅助方法 - formatTokens/formatAmount/formatTime等实用函数
🔧

优化建议(不影响现有前端调用)

重要说明

以下所有优化建议都是后端内部优化,不会改变API接口的输入输出格式,现有前端代码无需任何修改。

🚨 高优先级(建议近期实施)

1. 数据库事务保护 数据一致性

executeprotocol() 方法涉及多表操作(execution/billing/workflow_step),应使用事务确保原子性。

当前实现
// 多表操作无事务保护
$execution_id = Db::name('mxjson_execution')->insertGetId([...]);
// ... AI调用可能失败
Db::name('mxjson_execution')->update([...]);
Db::name('mxjson_billing')->insert([...]);
建议实现
public function executeprotocol() {
    Db::startTrans();
    try {
        $execution_id = Db::name('mxjson_execution')
            ->insertGetId([...]);
        
        // AI调用
        $result = $this->executeSimpleAI(...);
        
        // 更新执行状态
        Db::name('mxjson_execution')
            ->where('id', $execution_id)
            ->update([...]);
        
        // 计费处理
        $this->processBilling(...);
        
        Db::commit();
        return json(['code' => 0, ...]);
        
    } catch (\Exception $e) {
        Db::rollback();
        throw $e;
    }
}

2. AI调用重试机制 可靠性

AI接口调用可能因网络问题、限流等原因失败,需要增加自动重试机制。

/**
 * 带重试的AI调用(新增私有方法,不影响现有接口)
 */
private function callAIWithRetry(
    AiService $aiService,
    int $providerId,
    int $modelId,
    array $messages,
    array $options,
    int $maxRetries = 3
): array {
    $lastException = null;
    
    for ($i = 0; $i < $maxRetries; $i++) {
        try {
            return $aiService->chatCompletion(
                $providerId, $modelId, $messages, $options
            );
        } catch (\Exception $e) {
            $lastException = $e;
            
            // 判断是否可重试的错误
            if ($this->isRetryableError($e)) {
                // 指数退避: 200ms, 400ms, 800ms
                usleep((2 ** $i) * 200000);
                Log::warning("AI调用失败,第".($i+1)."次重试: ".$e->getMessage());
                continue;
            }
            throw $e;
        }
    }
    
    throw $lastException;
}

private function isRetryableError(\Exception $e): bool {
    $msg = strtolower($e->getMessage());
    return str_contains($msg, 'timeout') 
        || str_contains($msg, 'rate limit')
        || str_contains($msg, '503')
        || str_contains($msg, '502')
        || str_contains($msg, 'connection');
}

3. 脚本执行安全增强 安全

当前使用 eval() 执行用户脚本存在潜在风险,建议使用独立进程隔离。

/**
 * 安全沙箱执行(替换现有 executeSandboxedCode 方法)
 */
private function executeSandboxedCode(string $code, array $context): mixed {
    // 方案A:使用独立进程 + 资源限制(推荐)
    $tempFile = tempnam(sys_get_temp_dir(), 'mxjson_script_');
    $wrappedCode = $this->wrapCodeForExecution($code, $context);
    file_put_contents($tempFile, "<?php\n" . $wrappedCode);
    
    // 使用 proc_open 在受限环境执行
    $cmd = sprintf(
        'php -d disable_functions=exec,shell_exec,system,passthru,popen,proc_open '
        . '-d open_basedir=%s -d max_execution_time=5 %s',
        sys_get_temp_dir(),
        escapeshellarg($tempFile)
    );
    
    $descriptors = [
        0 => ['pipe', 'r'],
        1 => ['pipe', 'w'],
        2 => ['pipe', 'w']
    ];
    
    $process = proc_open($cmd, $descriptors, $pipes);
    
    if (is_resource($process)) {
        $stdout = stream_get_contents($pipes[1]);
        $stderr = stream_get_contents($pipes[2]);
        
        fclose($pipes[0]);
        fclose($pipes[1]);
        fclose($pipes[2]);
        
        $exitCode = proc_close($process);
        @unlink($tempFile);
        
        if ($exitCode !== 0) {
            throw new \Exception('脚本执行错误: ' . $stderr);
        }
        
        return json_decode($stdout, true) ?? $stdout;
    }
    
    @unlink($tempFile);
    throw new \Exception('无法创建脚本执行进程');
}

⚠️ 中优先级(建议后续迭代)

4. 执行超时全局控制 稳定性

防止长时间运行的工作流占用资源。

// 在 executeprotocol() 开头增加
$globalTimeout = $workflowConfig['timeout'] ?? 300; // 默认5分钟
$deadline = time() + $globalTimeout;

// 在 executeWorkflowStep() 中检查
if (time() > $deadline) {
    throw new \Exception("执行超时,已运行 {$globalTimeout} 秒");
}

5. 并发执行限制 资源保护

防止单用户同时执行过多任务导致资源耗尽。

// 在 executeprotocol() 开头增加检查
private function checkConcurrencyLimit(int $user_id, int $limit = 5): void {
    $runningCount = Db::name('mxjson_execution')
        ->where('user_id', $user_id)
        ->where('status', 'running')
        ->count();
    
    if ($runningCount >= $limit) {
        throw new \Exception("并发执行数量超限(当前:{$runningCount},上限:{$limit}),请稍后重试");
    }
}

6. 执行结果缓存 性能

对于相同输入的重复执行,可以缓存结果减少AI调用成本。

// 可选功能:结果缓存(需要在协议中配置 cache.enabled = true)
private function getCachedResult(string $protocol_id, array $input_data, int $ttl = 3600): ?array {
    $cacheKey = 'mxjson_result_' . md5($protocol_id . json_encode($input_data));
    
    if (Cache::has($cacheKey)) {
        $this->auditLog('cache_hit', 'info', '命中执行缓存', ['cache_key' => $cacheKey]);
        return Cache::get($cacheKey);
    }
    
    return null;
}

private function setCachedResult(string $protocol_id, array $input_data, array $result, int $ttl = 3600): void {
    $cacheKey = 'mxjson_result_' . md5($protocol_id . json_encode($input_data));
    Cache::set($cacheKey, $result, $ttl);
}

💡 低优先级(锦上添花)

7. 前端API请求重试 用户体验

网络不稳定时自动重试请求,提升用户体验。

// 在 axios 实例中增加拦截器(前端 utils/axios.ts)
import axios from 'axios';

const MAX_RETRIES = 3;
const RETRY_DELAY = 1000;

service.interceptors.response.use(
  response => response,
  async error => {
    const { config } = error;
    
    // 不重试的情况
    if (!config || config.__retryCount >= MAX_RETRIES) {
      return Promise.reject(error);
    }
    
    // 只重试网络错误和5xx错误
    const shouldRetry = !error.response || 
      (error.response.status >= 500 && error.response.status < 600);
    
    if (!shouldRetry) {
      return Promise.reject(error);
    }
    
    config.__retryCount = (config.__retryCount || 0) + 1;
    
    await new Promise(resolve => setTimeout(resolve, RETRY_DELAY * config.__retryCount));
    
    return service(config);
  }
);

8. 执行进度实时推送 用户体验

使用 SSE 或 WebSocket 实时推送工作流执行进度。

// 后端:在步骤执行时记录进度(可选功能)
private function broadcastProgress(int $execution_id, string $stepId, int $current, int $total): void {
    $progress = [
        'execution_id' => $execution_id,
        'current_step' => $stepId,
        'progress' => round($current / $total * 100),
        'message' => "正在执行: {$stepId} ({$current}/{$total})"
    ];
    
    // 写入Redis供SSE轮询
    Cache::set("mxjson:progress:{$execution_id}", $progress, 60);
}
优化总结

以上所有优化都是后端内部改进,API接口的输入输出格式保持不变:

  • ✅ 前端 mxjsonAPI.executeProtocol() 调用方式不变
  • ✅ 返回的 ExecutionResult 结构不变
  • ✅ 所有类型定义保持兼容
🔄

完整执行流程图

📊 主执行流程

MxJSON 协议执行主流程

🖥️ 前端提交
executeProtocol()
📥 接收请求
参数验证
📄 加载协议
从数据库读取
📋 解析配置
JSON解码
✅ 输入验证
validateInputData()
📝 创建执行记录
生成UUID/TraceID
🔄 预处理数据
preprocessInputData()
📦 构建上下文
Context对象
🔀 模式?
简单AI调用
executeSimpleAI()
工作流执行
executeWorkflow()
👤 人工审核?
✅ 完成执行
💰 计费处理
processBilling()
📊 更新状态
📝 审计日志
auditLog()
📤 返回结果

🔄 工作流执行子流程

工作流引擎执行流程(三种模式)

开始工作流
模式判断
Sequential
顺序执行
按步骤顺序逐个执行
Parallel
并行执行
所有步骤同时执行
DAG
有向无环图
按依赖关系拓扑执行
执行单个步骤
executeWorkflowStep()
ai_call
AI调用
human_review
人工审核
condition
条件判断
transform
数据转换
http.request
HTTP请求
script
脚本执行
loop
循环迭代
notify
消息通知
记录步骤结果
recordWorkflowStep()
更新上下文变量
返回工作流结果

🤖 AI调用子流程

AI 调用详细流程

接收AI配置
变量注入
injectVariables()
构建Messages
获取Provider
ai_providers表
获取Model
ai_model表
调用AiService
chatCompletion()
解析响应
提取JSON
extractJsonFromResponse()
Schema验证
validateOutputSchema()
返回结果
{raw_response, parsed_output, tokens_used}
📝

14步执行流程详解

前端发起请求

用户在前端填写表单,调用 mxjsonAPI.executeProtocol() 方法。

// 前端调用示例
const result = await mxjsonAPI.executeProtocol({
  protocol_id: 'abc123-def456',        // 协议ID
  input_data: {
    work_items: '1. 完成用户模块\n2. 修复登录bug',
    style: 'professional'
  },
  runtime_env: 'Production'             // 运行环境
});

// 实际发送的HTTP请求
POST /mxjson/mxjson/executeprotocol
Content-Type: application/json
{
  "protocol_id": "abc123-def456",
  "input_data": { "work_items": "...", "style": "professional" },
  "runtime_env": "Production"
}

后端接收并验证请求

控制器接收请求,使用 ThinkPHP Validate 验证必需参数。

// 后端 executeprotocol() 方法
$validate = Validate::rule([
    'protocol_id' => 'require',
    'input_data'  => 'require|array'
]);

if (!$validate->check($requestData)) {
    return json(['code' => 1, 'msg' => $validate->getError()]);
}

$protocol_id = $requestData['protocol_id'];
$input_data  = $requestData['input_data'];
$runtime_env = $requestData['runtime_env'] ?? 'Production';
$user_id     = $this->getUserId();

加载协议配置

从数据库加载协议定义,验证协议状态和访问权限。

// 从数据库加载协议
$protocol = Db::name('mxjson_protocol')
    ->where('id', $protocol_id)
    ->where('status', 1)             // 已启用
    ->where('deleted_at', null)     // 未删除
    ->where(function ($query) use ($user_id) {
        $query->where('is_public', 1)   // 公开
              ->whereOr('user_id', $user_id); // 或自己创建的
    })
    ->find();

if (!$protocol) {
    return json(['code' => 1, 'msg' => '协议不存在或已禁用']);
}

解析JSON配置

将数据库中的JSON字符串解析为PHP数组(input_schema、ai_config、workflow_config等)。

// 解析各项JSON配置
$inputSchema       = !empty($protocol['input_schema']) 
                       ? json_decode($protocol['input_schema'], true) : [];
$aiConfig          = !empty($protocol['ai_config']) 
                       ? json_decode($protocol['ai_config'], true) : [];
$workflowConfig    = !empty($protocol['workflow_config']) 
                       ? json_decode($protocol['workflow_config'], true) : null;
$humanReviewConfig = !empty($protocol['human_review_config']) 
                       ? json_decode($protocol['human_review_config'], true) : null;
$pricingConfig     = !empty($protocol['pricing_config']) 
                       ? json_decode($protocol['pricing_config'], true) : null;
$auditConfig       = !empty($protocol['audit_config']) 
                       ? json_decode($protocol['audit_config'], true) : null;

验证输入数据

根据 input_schema 验证用户输入(必填、类型、长度、范围、正则等)。

// validateInputData() 方法
foreach ($inputSchema as $fieldName => $fieldConfig) {
    $value = $inputData[$fieldName] ?? null;
    
    // 必填验证
    if (!empty($fieldConfig['required']) && empty($value)) {
        $errors[] = $fieldConfig['label'] . ' 不能为空';
    }
    
    // 类型验证(number/select/multiselect/json/boolean)
    switch ($fieldConfig['type']) {
        case 'number': // 数字验证
        case 'select': // 选项验证
        case 'json':   // JSON格式验证
    }
    
    // 自定义规则验证(min/max/min_length/max_length/pattern)
    if (isset($fieldConfig['validation'])) { ... }
}

创建执行记录

生成唯一标识(execution_uuid、trace_id),在数据库创建执行记录。

// 生成唯一标识
$execution_uuid = $this->generateUUID();
$trace_id = 'trace_' . date('Ymd') . '_' . bin2hex(random_bytes(8));

// 创建执行记录
$execution_id = Db::name('mxjson_execution')->insertGetId([
    'execution_uuid'  => $execution_uuid,
    'trace_id'        => $trace_id,
    'protocol_id'     => $protocol_id,
    'protocol_version'=> $protocol['version'],
    'runtime_env'     => $runtime_env,
    'input_data'      => json_encode($input_data, JSON_UNESCAPED_UNICODE),
    'status'          => 'running',
    'user_id'         => $user_id,
    'started_at'      => date('Y-m-d H:i:s'),
    'created_at'      => date('Y-m-d H:i:s')
]);

预处理输入数据

根据字段类型进行预处理(文件提取、日期格式化、JSON解析、数组转文本等)。

// preprocessInputData() 方法
foreach ($inputData as $fieldName => $value) {
    $type = $inputSchema[$fieldName]['type'] ?? 'text';
    
    switch ($type) {
        case 'file':
            // 提取文件内容
            $processed[$fieldName . '_text'] = $this->extractFileContent($value);
            break;
        case 'multiselect':
            // 数组转文本
            $processed[$fieldName . '_text'] = implode('、', $value);
            break;
        case 'date':
            // 日期格式化
            $processed[$fieldName . '_formatted'] = date('Y年m月d日', strtotime($value));
            break;
        case 'json':
            // JSON解析
            $processed[$fieldName . '_parsed'] = json_decode($value, true);
            break;
    }
}

构建执行上下文

将所有数据组装成上下文对象,供变量注入使用。

// 构建完整的执行上下文
$context = [
    'input'        => $input_data,       // 原始输入数据
    'preprocessed' => $processedData,   // 预处理后的数据
    'ai'           => $aiConfig,        // AI配置
    'meta'         => $rawJsonData['meta'] ?? [], // 协议元数据
    'runtime'      => [
        'env'          => $runtime_env,
        'execution_id' => $execution_id,
        'trace_id'     => $trace_id,
        'user_id'      => $user_id
    ]
];

// 工作流执行时,上下文会动态扩展
// 例如: $context['step1_result'] = ... // 前置步骤的输出

判断执行模式并执行

根据是否有工作流配置,选择简单AI调用或工作流执行。

// 判断执行模式
if ($workflowConfig && !empty($workflowConfig['steps'])) {
    // 工作流模式:支持 sequential/parallel/dag 三种
    $result = $this->executeWorkflow(
        $execution_id, 
        $workflowConfig,  // 工作流配置
        $context,         // 执行上下文
        $aiConfig,        // AI配置
        $humanReviewConfig,
        $trace_id,
        $auditConfig
    );
} else {
    // 简单AI调用模式:直接调用AI
    $result = $this->executeSimpleAI(
        $execution_id, 
        $aiConfig,        // AI配置
        $context,         // 执行上下文
        $trace_id,
        $auditConfig
    );
}

变量注入(核心)

{{input.work_items}} 等变量占位符替换为实际值,支持过滤器。

// injectVariables() 方法 - 变量注入引擎
private function injectVariables(string $template, array $context): string {
    return preg_replace_callback(
        '/\{\{([^}]+)\}\}/',
        function ($matches) use ($context) {
            $expression = trim($matches[1]);
            
            // 支持过滤器语法: {{variable|filter(args)}}
            if (strpos($expression, '|') !== false) {
                $parts = explode('|', $expression, 2);
                $value = $this->getValueByPath($context, trim($parts[0]));
                return $this->applyFilter($value, trim($parts[1]));
            }
            
            return $this->getValueByPath($context, $expression);
        },
        $template
    );
}

// 示例:
// 模板: "请生成{{input.style}}风格的周报:{{input.work_items}}"
// 结果: "请生成professional风格的周报:1. 完成用户模块..."

// 支持的过滤器:join/upper/lower/trim/length/first/last/default/truncate/json/date/number_format/replace

调用AI服务

通过 AiService 调用配置的AI模型(OpenAI/Claude/通义千问/GLM等)。

// 获取AI提供商和模型配置
$provider = $this->getProviderByName($aiConfig['provider'] ?? 'openai');
$model = $this->getModelByName($aiConfig['model'] ?? 'gpt-4o', $provider['id']);

// 构建消息
$messages = [];
if (!empty($systemPrompt)) {
    $messages[] = ['role' => 'system', 'content' => $systemPrompt];
}
$messages[] = ['role' => 'user', 'content' => $userPrompt];

// 调用AI服务
$aiService = new AiService();
$response = $aiService->chatCompletion(
    $provider['id'],
    $model['id'],
    $messages,
    [
        'temperature' => 0.7,
        'max_tokens'  => 2000,
        'top_p'       => 1.0
    ]
);

解析AI响应

尝试从响应中提取JSON,如果配置了output_format则进行Schema验证。

// extractJsonFromResponse() - 从响应中提取JSON
$parsedOutput = $response['content'];

// 尝试提取JSON(支持代码块格式)
$jsonOutput = $this->extractJsonFromResponse($response['content']);
if ($jsonOutput !== null) {
    $parsedOutput = $jsonOutput;
    
    // 如果配置了输出Schema,进行验证
    if (isset($outputFormat['schema'])) {
        $validation = $this->validateOutputSchema(
            $jsonOutput, 
            $outputFormat['schema']
        );
        if (!$validation['valid']) {
            $this->logExecution($execution_id, null, 'warning', 
                'schema_validation', 'AI输出Schema验证失败');
        }
    }
}

人工审核判断 & 计费处理

检查是否需要人工审核,计算并记录费用。

// 人工审核判断
if ($humanReviewConfig && !empty($humanReviewConfig['enabled'])) {
    $needReview = $this->evaluateHumanReviewCondition(
        $humanReviewConfig, $result, $context
    );
    if ($needReview) {
        $this->createHumanReview($execution_id, $humanReviewConfig, $result, $context);
        // 状态变为 'reviewing',等待人工处理
    }
}

// 计费处理 - 支持8种模式
$billingResult = $this->processBilling($execution_id, $pricingConfig, $result, $user_id);

// 计费模式: free/per_call/per_token/per_minute/subscription/tiered/usage_based/hybrid

更新状态并返回结果

更新执行记录状态,记录审计日志,返回完整结果给前端。

// 更新执行状态
Db::name('mxjson_execution')->where('id', $execution_id)->update([
    'status'            => 'completed',
    'ai_response'       => $result['raw_response'],
    'parsed_output'     => json_encode($result['parsed_output']),
    'final_output'      => json_encode($result['final_output']),
    'execution_time_ms' => $executionTimeMs,
    'tokens_used'       => $result['tokens_used'],
    'completed_at'      => date('Y-m-d H:i:s')
]);

// 更新协议使用次数
Db::name('mxjson_protocol')->where('id', $protocol_id)->inc('usage_count')->update();

// 记录审计日志
$this->auditLog('execution_completed', 'info', '协议执行完成', [...], $trace_id);

// 返回结果给前端
return json([
    'code' => 0,
    'msg'  => '执行成功',
    'data' => [
        'execution_id'   => $execution_id,
        'execution_uuid' => $execution_uuid,
        'trace_id'       => $trace_id,
        'status'         => 'completed',
        'result'         => $result,      // {raw_response, parsed_output, final_output, tokens_used}
        'billing'        => $billingResult // {bill_id, mode, amount, currency, tokens_used}
    ]
]);
🏗️

系统架构图

┌─────────────────────────────────────────────────────────────────────────────────┐
│                            前端层 (Vue3 + TypeScript + Element Plus)              │
├─────────────────────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐           │
│  │ProtocolList  │ │ExecutionList │ │ExecutionDetail│ │ ReviewList   │           │
│  │  协议列表     │ │  执行记录    │ │  执行详情     │ │  人工审核    │           │
│  └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘           │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐                            │
│  │MxjsonConsole │ │TemplateList  │ │  Dashboard   │                            │
│  │  协议控制台   │ │  模板列表    │ │  数据统计    │                            │
│  └──────────────┘ └──────────────┘ └──────────────┘                            │
│                                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                        mxjsonAPI (api/mxjson/index.ts)                 │   │
│  │  • 完整TypeScript类型定义 (30+ interfaces)                               │   │
│  │  • 辅助方法 (formatTokens/formatAmount/formatTime...)                   │   │
│  │  • 常量列表 (getCategories/getStatusList/getPricingModes...)           │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────────┘
                                       │ HTTP REST API
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                          控制器层 (ThinkPHP8 - Mxjson.php)                      │
├─────────────────────────────────────────────────────────────────────────────────┤
│  ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐   │
│  │ 协议管理 API    │ │ 执行记录 API   │ │ 人工审核 API   │ │ 计费/审计 API  │   │
│  │ getprotocols   │ │ getexecutions  │ │ getreviewlist  │ │ getbillingrecords│ │
│  │ createprotocol │ │ getexecutiondet│ │ submitreview   │ │ getauditlogs   │   │
│  │ updateprotocol │ │                │ │                │ │                │   │
│  │ deleteprotocol │ │                │ │                │ │                │   │
│  └────────────────┘ └────────────────┘ └────────────────┘ └────────────────┘   │
│                                                                                 │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                        executeprotocol() - 核心执行入口               │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────────┘
                                       │
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                               核心引擎层                                        │
├─────────────────────────────────────────────────────────────────────────────────┤
│  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐              │
│  │协议解析器         │  │工作流引擎         │  │步骤执行器         │              │
│  │validateMxjsonSchema│ │executeWorkflow   │  │executeWorkflowStep│             │
│  │• Schema验证       │  │• Sequential模式  │  │• ai_call         │              │
│  │• 循环检测(DFS)    │  │• Parallel模式    │  │• human_review    │              │
│  │• 变量引用验证     │  │• DAG模式         │  │• condition       │              │
│  └──────────────────┘  └──────────────────┘  │• transform       │              │
│                                              │• http.request    │              │
│  ┌──────────────────┐  ┌──────────────────┐  │• script          │              │
│  │变量插值引擎       │  │计费引擎           │  │• loop/parallel   │              │
│  │injectVariables   │  │processBilling    │  │• notify/delay    │              │
│  │• 嵌套路径访问    │  │• 8种计费模式     │  └──────────────────┘              │
│  │• 数组索引        │  │• 阶梯计算        │                                    │
│  │• 13种过滤器      │  │• 分账处理        │  ┌──────────────────┐              │
│  └──────────────────┘  └──────────────────┘  │审计日志           │              │
│                                              │auditLog          │              │
│  ┌──────────────────┐  ┌──────────────────┐  │• 多级别日志      │              │
│  │UIRenderer        │  │MxpPackageLoader  │  │• 智能脱敏        │              │
│  │• HTML/JSON/Vue   │  │• ZIP解压         │  │• 双重存储        │              │
│  │• 26种组件        │  │• 结构验证        │  └──────────────────┘              │
│  └──────────────────┘  └──────────────────┘                                    │
└─────────────────────────────────────────────────────────────────────────────────┘
                                       │
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                               服务层                                            │
├─────────────────────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                           AiService - 多模型AI网关                     │   │
│  │  • chatCompletion() - 统一调用接口                                       │   │
│  │  • 支持: OpenAI / Anthropic / 阿里云 / 智谱 / DeepSeek / Moonshot       │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────────────┘
                                       │
                                       ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                            数据层 (MySQL)                                      │
├─────────────────────────────────────────────────────────────────────────────────┤
│  mxjson_protocol │ mxjson_execution │ mxjson_workflow_step │ mxjson_human_review│
│  mxjson_billing  │ mxjson_audit_log │ mxjson_execution_log │ mxjson_template    │
│  ai_providers    │ ai_model         │ mxjson_action_registry                    │
└─────────────────────────────────────────────────────────────────────────────────┘
📊

数据流与变量系统

🔀 变量引用路径

变量路径 说明 示例
{{input.field_name}}原始输入字段{{input.work_items}}
{{preprocessed.field_text}}预处理后的字段{{preprocessed.file_text}}
{{step_id.output}}前置步骤的输出{{step1.result}}
{{runtime.trace_id}}运行时信息{{runtime.user_id}}
{{meta.name}}协议元数据{{meta.version}}
{{input.items[0]}}数组索引访问{{input.tags[2]}}
{{input.items|join(、)}}使用过滤器{{input.name|upper}}

🎛️ 支持的过滤器(13种)

过滤器用法说明
join{{items|join(,)}}数组转字符串
upper{{name|upper}}转大写
lower{{name|lower}}转小写
trim{{text|trim}}去首尾空格
length{{items|length}}获取长度
first{{items|first}}取第一个
last{{items|last}}取最后一个
default{{name|default('未知')}}默认值
truncate{{text|truncate(100,...)}}截断字符串
json{{obj|json}}转JSON字符串
date{{time|date(Y-m-d)}}格式化日期
number_format{{price|number_format(2)}}数字格式化
replace{{text|replace(a,b)}}替换字符串

📋 条件表达式运算符(12种)

运算符示例说明
=={{input.status}} == "approved"等于
!={{input.type}} != "draft"不等于
> / <{{input.score}} > 80大于/小于
>= / <={{input.count}} >= 10大于等于/小于等于
contains{{input.text}} contains "风险"包含字符串
starts_with{{input.code}} starts_with "ERR"以...开头
ends_with{{input.file}} ends_with ".pdf"以...结尾
in{{input.status}} in ["a","b","c"]在数组中
not_in{{input.type}} not_in ["x","y"]不在数组中
empty{{input.comment}} empty为空
not_empty{{input.file}} not_empty不为空
exists{{input.option}} exists存在且非空

📦 核心数据结构

// 1. 执行请求 (前端 → 后端)
{
  "protocol_id": "abc123-def456",
  "input_data": {
    "work_items": "1. 完成用户模块...",
    "style": "professional"
  },
  "runtime_env": "Production"
}

// 2. 执行上下文 (后端内部)
{
  "input": { "work_items": "...", "style": "..." },
  "preprocessed": { "work_items_text": "..." },
  "ai": { "provider": "openai", "model": "gpt-4o" },
  "meta": { "name": "周报生成器" },
  "runtime": { 
    "execution_id": 123,
    "trace_id": "trace_20250113_xxx",
    "user_id": 1
  },
  // 工作流执行时动态添加
  "step1_result": { "output": "..." },
  "step2_result": { "output": "..." }
}

// 3. 执行结果 (后端 → 前端)
{
  "code": 0,
  "msg": "执行成功",
  "data": {
    "execution_id": 123,
    "execution_uuid": "abc-123-def-456",
    "trace_id": "trace_20250113_xxx",
    "status": "completed",
    "result": {
      "raw_response": "# 周报\n\n## 一、本周工作...",
      "parsed_output": { /* 如果是JSON则解析 */ },
      "final_output": "...",
      "tokens_used": 1500,
      "usage": {
        "prompt_tokens": 500,
        "completion_tokens": 1000,
        "total_tokens": 1500
      }
    },
    "billing": {
      "bill_id": "bill_xxx",
      "mode": "per_token",
      "amount": 0.03,
      "currency": "CNY",
      "tokens_used": 1500
    }
  }
}