模型上下文通讯协议 (MCP-CP)
版本:1.0.0
目录
1. 协议概述
1.1 目的
本协议定义了AI模型与上下文系统之间的标准化通讯格式和流程,旨在提供清晰、一致、可扩展的通讯机制,特别适用于需要工具调用和复杂指令处理的场景。
1.2 适用范围
适用于所有基于MCP系统的AI模型与上下文管理系统之间的通讯,包括但不限于:
- 模型生成请求与响应
- 工具调用请求与结果处理
- 多步骤指令任务协调
- 上下文状态更新与同步
1.3 术语定义
- 消息(Message):通讯的基本单位,包含特定类型的内容
- 上下文(Context):对话或交互的状态容器,包含历史消息和元数据
- 工具调用(Tool Call):模型请求执行外部工具或功能的过程
- 指令(Instruction):要求模型或系统执行特定操作的命令
- 依赖关系(Dependency):指令之间的前后执行关系或数据传递关系
2. 通讯基本结构
2.1 通讯模型
本协议采用基于JSON的请求-响应模式,通讯双方包括:
- 客户端:发起请求的一方,可以是用户应用、模型推理服务等
- 服务端:处理请求的一方,可以是上下文管理系统、工具执行环境等
2.2 基本消息结构
所有通讯消息必须遵循以下基本结构:
{
"messageId": "msg_123456789", // 消息唯一标识,用于跟踪和引用特定消息
"contextId": "ctx_abcdefg", // 所属上下文ID,关联消息到特定的对话或交互上下文
"timestamp": "2025-12-01T12:34:56.789Z", // ISO 8601格式时间戳,记录消息创建时间
"type": "MESSAGE_TYPE", // 消息类型,如USER_INPUT、MODEL_RESPONSE等
"sender": { // 发送方信息,标识消息的来源
"id": "sender_id", // 发送者唯一标识
"type": "USER|MODEL|SYSTEM|TOOL" // 发送者类型:用户、模型、系统或工具
},
"content": { // 消息内容,结构取决于消息类型
// 根据不同消息类型定义的内容结构
},
"metadata": { // 可选元数据,存储额外的上下文相关信息
// 自定义键值对,如客户端信息、会话数据等
}
}
2.3 通讯流程
基本通讯流程如下:
- 客户端发送请求消息到服务端
- 服务端处理请求
- 判断当前请求是否存在指令意图
- 根据指令意图判断映射对应系统提示词和设置模型返回指定类型
- 调用模型得到响应
- 可能会执行工具调用或其他操作
- 服务端返回响应消息到客户端
- 对于异步操作,服务端可能发送多个响应消息
3. 消息类型定义
3.1 用户输入消息
用户向模型发送的输入消息。
{
"type": "USER_INPUT", // 消息类型:用户输入
"content": {
"text": "用户输入的文本内容", // 用户发送的文本内容
"attachments": [ // 可选附件列表,支持多媒体内容
{
"type": "IMAGE|FILE|AUDIO|VIDEO", // 附件类型:图片、文件、音频或视频
"url": "资源URL", // 附件资源的访问地址
"metadata": { // 附件相关的元数据
"fileName": "example.jpg", // 文件名
"fileSize": 1024, // 文件大小(字节)
"mimeType": "image/jpeg" // MIME类型
}
}
]
}
}
3.2 模型响应消息
模型生成的响应消息。
{
"type": "MODEL_RESPONSE", // 消息类型:模型响应
"content": {
"text": "模型生成的文本内容", // 模型生成的文本响应
"toolCalls": [ // 可选的工具调用列表,当模型需要调用外部工具时使用
// 工具调用对象,详见工具调用规范
],
"finishReason": "STOP|LENGTH|TOOL_CALLS|ERROR", // 生成结束原因:
// STOP - 自然结束
// LENGTH - 达到最大长度限制
// TOOL_CALLS - 因需要工具调用而停止
// ERROR - 生成过程中出现错误
"usage": { // 可选的资源使用情况统计
"promptTokens": 123, // 提示词使用的token数量
"completionTokens": 456, // 生成内容使用的token数量
"totalTokens": 579 // 总token使用量
}
}
}
3.3 工具调用请求
模型请求执行工具的消息。
{
"type": "TOOL_CALL_REQUEST", // 消息类型:工具调用请求
"content": {
"calls": [ // 工具调用列表,可包含多个工具调用请求
{
"callId": "call_123456", // 调用唯一标识,用于后续引用和关联结果
"name": "tool_name", // 工具名称,标识要调用的具体工具
"parameters": { // 工具参数,传递给工具的输入数据
"param1": "value1", // 字符串参数示例
"param2": 123, // 数值参数示例
"param3": { // 对象参数示例
"subParam1": "value"
}
},
"description": "调用描述" // 可选描述,说明调用目的
}
],
"executionMode": "SYNC|ASYNC|PARALLEL|SEQUENTIAL", // 执行模式:
// SYNC - 同步执行,等待完成
// ASYNC - 异步执行,不等待完成
// PARALLEL - 并行执行多个调用
// SEQUENTIAL - 按顺序执行多个调用
"timeout": 30 // 超时时间(秒),超过此时间视为调用失败
}
}
3.4 工具调用响应
工具执行结果的响应消息。
{
"type": "TOOL_CALL_RESPONSE", // 消息类型:工具调用响应
"content": {
"results": [ // 工具调用结果列表,对应请求的每个调用
{
"callId": "call_123456", // 对应请求的调用ID,用于关联请求和响应
"status": "SUCCESS|ERROR|TIMEOUT", // 执行状态:
// SUCCESS - 成功完成
// ERROR - 执行出错
// TIMEOUT - 执行超时
"result": { // 执行结果,可为任意JSON结构
"data": "结果数据", // 工具返回的主要数据
"metadata": { // 结果相关元数据
"processingTime": 120 // 处理时间(毫秒)
}
},
"error": { // 错误信息,仅在status为ERROR时存在
"code": "ERROR_CODE", // 错误代码,用于标识错误类型
"message": "错误描述", // 人类可读的错误描述
"details": { // 详细错误信息
"stackTrace": "..." // 可能包含堆栈跟踪等调试信息
}
},
"executionTime": 1234 // 执行耗时(毫秒),从请求到响应的总时间
}
]
}
}
3.5 系统消息
系统发送的控制消息或通知。
{
"type": "SYSTEM_MESSAGE", // 消息类型:系统消息
"content": {
"action": "NOTIFICATION|WARNING|ERROR|INFO", // 消息动作类型:
// NOTIFICATION - 普通通知
// WARNING - 警告信息
// ERROR - 错误信息
// INFO - 信息提示
"text": "系统消息内容", // 系统消息的文本内容
"data": { // 可选的相关数据
"code": "SYS_001", // 系统消息代码
"severity": "medium", // 严重程度
"affectedComponents": ["auth", "storage"] // 受影响的组件
}
}
}
3.6 指令消息
包含一个或多个指令的消息。
{
"type": "INSTRUCTION", // 消息类型:指令消息
"content": {
"instructions": [ // 指令列表,包含一个或多个指令
{
"instructionId": "inst_123456", // 指令唯一标识,用于引用和依赖关系
"action": "QUERY_DATA", // 指令动作,指定要执行的具体操作
"parameters": { // 指令参数,操作所需的输入数据
"query": "SELECT * FROM users", // 查询语句
"limit": 10, // 结果限制数量
"offset": 0 // 结果偏移量
},
"dependencies": [ // 依赖的其他指令ID列表,指定执行顺序
"inst_abcdef" // 依赖的指令ID
],
"condition": "dependencies.inst_abcdef.result.count > 0" // 执行条件,满足时才执行
}
],
"executionMode": "SEQUENTIAL|PARALLEL|CONDITIONAL", // 执行模式:
// SEQUENTIAL - 按顺序执行
// PARALLEL - 并行执行
// CONDITIONAL - 条件执行
"timeout": 60 // 整体超时时间(秒),所有指令的执行总时间限制
}
}
4. 工具调用规范
4.1 工具调用JSON格式
当模型需要调用工具时,应在响应中包含格式规范的toolCalls
数组:
{
"toolCalls": [ // 工具调用数组
{
"callId": "call_123456", // 调用唯一标识,用于跟踪和关联结果
"name": "toolName", // 工具名称,指定要调用的工具
"parameters": { // 工具参数对象,包含调用所需的所有参数
"param1": "value1", // 字符串参数
"param2": 123, // 数值参数
"param3": { // 嵌套对象参数
"subParam1": "subValue1" // 子参数
}
},
"description": "此次调用的目的是...", // 可选的调用描述,解释调用意图
"requiredAfter": ["call_abcdef"], // 依赖的其他调用ID,指定必须在这些调用完成后执行
"timeout": 30 // 可选的超时时间(秒),此调用的最大等待时间
}
]
}
4.2 工具调用类型
4.2.1 功能型工具
执行特定功能或计算的工具。
{
"callId": "call_123456", // 调用唯一标识
"name": "calculator", // 工具名称:计算器工具
"parameters": {
"expression": "2*(3+4)" // 要计算的数学表达式
}
}
4.2.2 数据查询工具
查询或检索数据的工具。
{
"callId": "call_123456", // 调用唯一标识
"name": "database_query", // 工具名称:数据库查询工具
"parameters": {
"query": "SELECT * FROM products WHERE price < 100", // SQL查询语句
"limit": 10, // 结果数量限制
"database": "product_db", // 目标数据库
"timeout": 5 // 查询超时时间(秒)
}
}
4.2.3 外部API调用
调用外部服务API的工具。
{
"callId": "call_123456", // 调用唯一标识
"name": "weather_api", // 工具名称:天气API
"parameters": {
"city": "北京", // 查询的城市名称
"forecast_days": 3, // 预报天数
"units": "metric", // 温度单位(公制)
"include_details": true // 是否包含详细信息
}
}
4.2.4 内容生成工具
生成特定内容的工具。
{
"callId": "call_123456", // 调用唯一标识
"name": "image_generator", // 工具名称:图像生成器
"parameters": {
"prompt": "一只在雪地中奔跑的狼", // 生成提示词
"size": "1024x1024", // 图像尺寸
"style": "realistic", // 图像风格
"format": "png", // 输出格式
"seeds": [42, 123], // 随机种子,用于可重复生成
"negative_prompt": "模糊,低质量" // 负面提示词,指定不希望出现的元素
}
}
4.3 工具调用执行模式
工具调用可以按不同模式执行:
- 同步(SYNC):等待工具执行完成后再继续
- 异步(ASYNC):不等待工具执行完成,后续通过回调获取结果
- 并行(PARALLEL):多个工具同时执行
- 顺序(SEQUENTIAL):多个工具按顺序执行
{
"type": "TOOL_CALL_REQUEST",
"content": {
"calls": [ // 工具调用列表
{
"callId": "call_001", // 第一个工具调用
"name": "weather_api",
"parameters": {
"city": "北京"
}
},
{
"callId": "call_002", // 第二个工具调用
"name": "news_api",
"parameters": {
"topic": "天气"
}
}
],
"executionMode": "PARALLEL", // 执行模式:并行执行两个API调用
"timeout": 30 // 总超时时间(秒)
}
}
4.4 工具调用结果处理
工具调用结果应包含以下信息:
{
"callId": "call_123456", // 对应请求的调用ID
"status": "SUCCESS", // 执行状态:成功
"result": { // 执行结果对象
"value": 14, // 结果主值,如计算结果
"unit": "meters", // 可选的单位,指定值的度量单位
"confidence": 0.95, // 可选的置信度,表示结果的可信程度(0-1)
"parsed": true, // 是否已解析结构化数据
"source": "primary_database", // 数据来源
"timestamp": "2025-12-01T12:34:56Z" // 结果生成时间
},
"executionTime": 123 // 执行耗时(毫秒)
}
4.5 前端工具调用规范
除了后端工具外,本协议也支持调用前端(客户端)工具。前端工具通常在用户设备上直接执行,可以访问客户端特有的功能和资源。
4.5.1 前端工具定义
前端工具在定义时需要明确指定其执行环境:
{
"toolId": "frontend_screenshot", // 工具唯一标识
"name": "截图工具", // 工具名称
"description": "捕获当前屏幕内容", // 工具描述
"version": "1.0.0", // 工具版本
"runtime": "FRONTEND", // 执行环境:FRONTEND表示前端工具
"capabilities": [ // 工具能力列表
"SCREEN_CAPTURE", // 屏幕捕获能力
"FILE_SYSTEM" // 文件系统访问能力
],
"parameters": { // 参数定义
"type": "object",
"properties": {
"region": {
"type": "string",
"enum": ["full", "selection", "window"],
"description": "截图区域类型"
},
"format": {
"type": "string",
"enum": ["png", "jpg", "webp"],
"default": "png",
"description": "图像格式"
}
}
},
"returns": { // 返回值定义
"type": "object",
"properties": {
"imageData": {
"type": "string",
"format": "base64",
"description": "Base64编码的图像数据"
},
"metadata": {
"type": "object",
"description": "图像元数据"
}
}
},
"permissionLevel": "USER_CONSENT" // 权限级别:需要用户同意
}
4.5.2 前端工具调用流程
前端工具调用流程与后端工具有所不同:
- 模型发起调用请求:模型通过标准工具调用格式请求调用前端工具
- 服务端转发请求:服务端识别为前端工具请求,将请求转发至前端
- 前端权限确认:前端根据工具的权限级别可能需要向用户请求授权
- 前端执行工具:授权通过后,前端执行工具并收集结果
- 结果返回服务端:前端将执行结果返回给服务端
- 服务端转发结果:服务端将结果转发给模型继续处理
前端工具调用示例:
{
"callId": "call_frontend_123456", // 调用唯一标识
"name": "frontend_screenshot", // 前端工具名称
"runtime": "FRONTEND", // 指定在前端执行
"parameters": { // 调用参数
"region": "selection", // 截取选定区域
"format": "png" // PNG格式
},
"userPrompt": "此操作将截取您选择的屏幕区域,是否允许?", // 向用户显示的提示
"fallbackBehavior": "ABORT" // 如果无法执行,则终止
}
4.5.3 前端工具特有属性
前端工具调用可以包含以下特有属性:
- runtime:明确指定
"FRONTEND"
,表示在前端执行 - userPrompt:向用户显示的授权提示文本
- fallbackBehavior:当工具不可用时的行为(
ABORT
、SKIP
或USE_ALTERNATIVE
) - uiSettings:用于控制工具UI展示的参数
- timeoutClient:在客户端的超时时间,可能与服务端超时不同
4.5.4 前端工具响应
前端工具执行后的响应示例:
{
"callId": "call_frontend_123456", // 对应的调用ID
"status": "SUCCESS", // 执行状态
"result": { // 执行结果
"imageData": "data:image/png;base64,iVBORw0KGgoAAA...", // 图像数据
"metadata": {
"width": 800, // 图像宽度
"height": 600, // 图像高度
"captureTime": "2025-12-01T15:30:45Z", // 捕获时间
"deviceInfo": "Windows 10, Chrome 96" // 设备信息
}
},
"clientInfo": { // 客户端信息,前端工具特有
"deviceType": "desktop", // 设备类型
"browser": "chrome", // 浏览器类型
"version": "96.0.4664.110", // 版本号
"capabilities": ["camera", "microphone", "geolocation"] // 设备能力
},
"executionTime": 350 // 执行耗时(毫秒)
}
4.5.5 前端工具类型
常见的前端工具类型包括:
- UI交互工具:控制或修改用户界面元素
{
"callId": "call_ui_101",
"name": "highlight_element",
"runtime": "FRONTEND",
"parameters": {
"selector": "#main-content",
"style": "pulse",
"duration": 3000
}
}
- 客户端资源访问工具:访问本地文件、摄像头、麦克风等
{
"callId": "call_resource_102",
"name": "access_camera",
"runtime": "FRONTEND",
"parameters": {
"mode": "photo",
"resolution": "high"
}
}
- 本地数据处理工具:在客户端进行数据处理,避免数据传输
{
"callId": "call_process_103",
"name": "local_image_resize",
"runtime": "FRONTEND",
"parameters": {
"imageId": "img_12345",
"width": 300,
"height": 200,
"preserveAspectRatio": true
}
}
- 设备特性工具:访问设备特有功能,如地理位置、通知、传感器
{
"callId": "call_device_104",
"name": "geolocation",
"runtime": "FRONTEND",
"parameters": {
"accuracy": "high",
"timeout": 5000
}
}
4.6 前后端工具协同
在复杂场景中,可能需要前后端工具协同工作。
4.6.1 工具依赖链
前后端工具可以形成依赖链,前端工具的输出可以作为后端工具的输入,反之亦然:
{
"toolCalls": [
{
"callId": "call_frontend_201",
"name": "file_picker", // 前端文件选择工具
"runtime": "FRONTEND",
"parameters": {
"accept": ".jpg,.png",
"multiple": false
}
},
{
"callId": "call_backend_202",
"name": "image_analyze", // 后端图像分析工具
"parameters": {
"imageData": "${results.call_frontend_201.result.fileData}", // 使用前端工具的结果
"analyzeType": "object_detection"
},
"requiredAfter": ["call_frontend_201"] // 依赖前端工具执行完成
},
{
"callId": "call_frontend_203",
"name": "display_overlay", // 前端显示叠加层工具
"runtime": "FRONTEND",
"parameters": {
"sourceImageId": "${results.call_frontend_201.result.fileId}",
"overlayData": "${results.call_backend_202.result.detections}", // 使用后端工具的结果
"style": "bounding_boxes"
},
"requiredAfter": ["call_backend_202"] // 依赖后端工具执行完成
}
],
"executionMode": "SEQUENTIAL", // 顺序执行模式
"timeout": 60 // 总超时时间(秒)
}
4.6.2 混合执行模式
针对前后端混合工具调用,支持特殊的执行模式:
- FRONTEND_FIRST:先执行所有前端工具,再执行后端工具
- BACKEND_FIRST:先执行所有后端工具,再执行前端工具
- CLIENT_SERVER_PARALLEL:前后端工具并行执行,但各自内部保持指定顺序
{
"type": "TOOL_CALL_REQUEST",
"content": {
"calls": [
/* 前端和后端工具列表 */
],
"executionMode": "FRONTEND_FIRST", // 前端优先执行模式
"frontendTimeout": 20, // 前端工具总超时时间(秒)
"backendTimeout": 30 // 后端工具总超时时间(秒)
}
}
4.6.3 安全考虑
前后端工具协同涉及特殊的安全考虑:
- 数据最小化:仅传输必要的数据,敏感数据优先在前端处理
- 权限分离:前端工具和后端工具拥有不同的权限范围
- 用户确认:对于敏感操作,必须获得用户明确授权
- 传输安全:前后端数据传输必须加密并验证完整性
- 跨站保护:防止跨站请求伪造(CSRF)和跨站脚本(XSS)攻击
4.7 前端工具注册与发现
客户端需要支持工具注册与发现机制,以便模型了解可用的前端工具。
4.7.1 客户端能力公告
客户端在连接时应向服务端公告其支持的工具和能力:
{
"type": "CLIENT_CAPABILITIES",
"content": {
"clientId": "client_abc123", // 客户端标识
"deviceType": "smartphone", // 设备类型
"platform": "iOS", // 平台
"version": "15.0", // 版本
"supportedTools": [ // 支持的前端工具列表
{
"toolId": "frontend_camera",
"version": "1.2.0",
"capabilities": ["photo", "video", "ar"]
},
{
"toolId": "frontend_location",
"version": "1.0.1",
"capabilities": ["gps", "network", "altitude"]
}
],
"supportedFeatures": [ // 支持的特性
"offline_execution",
"background_processing",
"push_notifications"
],
"limitations": { // 限制
"maxFileSize": 50000000, // 最大文件大小(字节)
"maxProcessingTime": 60000 // 最大处理时间(毫秒)
}
}
}
4.7.2 工具可用性查询
模型可以查询特定前端工具的可用性:
{
"type": "TOOL_AVAILABILITY_REQUEST",
"content": {
"tools": [
{
"toolId": "frontend_camera",
"minVersion": "1.0.0",
"requiredCapabilities": ["photo"]
},
{
"toolId": "frontend_location",
"minVersion": "1.0.0"
}
]
}
}
服务端响应包含工具可用性信息:
{
"type": "TOOL_AVAILABILITY_RESPONSE",
"content": {
"availableTools": [
{
"toolId": "frontend_camera",
"available": true,
"version": "1.2.0",
"capabilities": ["photo", "video", "ar"]
},
{
"toolId": "frontend_location",
"available": false,
"reason": "PERMISSION_DENIED",
"message": "用户未授权位置访问"
}
]
}
}
5. 多指令处理机制
5.1 指令基本结构
指令是对模型或系统的操作请求,具有以下结构:
{
"instructionId": "inst_123456", // 指令唯一标识,用于引用和依赖管理
"action": "ACTION_NAME", // 指令动作名称,指定要执行的操作类型
"parameters": { // 指令参数对象
"param1": "value1", // 字符串参数
"param2": 123, // 数值参数
"param3": ["item1", "item2"], // 数组参数
"param4": { // 对象参数
"subParam1": true // 布尔子参数
}
},
"dependencies": [ // 依赖的其他指令ID数组
"inst_abcdef", // 此指令依赖的前置指令ID
"inst_ghijkl" // 可以有多个依赖
],
"condition": "dependencies.inst_abcdef.status == 'SUCCESS'" // 执行条件表达式,满足时才执行
}
5.2 指令类型
常见的指令类型包括:
- 查询指令(QUERY):获取信息或数据
- 操作指令(OPERATION):执行特定操作
- 生成指令(GENERATION):生成内容
- 分析指令(ANALYSIS):分析数据或内容
- 决策指令(DECISION):做出决策
5.3 指令组合模式
多个指令可以组合为任务,按以下模式执行:
5.3.1 顺序执行
指令按顺序依次执行,前一个指令完成后再执行下一个。
{
"type": "INSTRUCTION",
"content": {
"instructions": [ /* 指令列表 */ ],
"executionMode": "SEQUENTIAL"
}
}
5.3.2 并行执行
多个指令同时执行,适用于彼此独立的指令。
{
"type": "INSTRUCTION",
"content": {
"instructions": [ /* 指令列表 */ ],
"executionMode": "PARALLEL"
}
}
5.3.3 条件执行
根据条件决定是否执行特定指令。
{
"type": "INSTRUCTION",
"content": {
"instructions": [ /* 指令列表 */ ],
"executionMode": "CONDITIONAL"
}
}
5.4 指令执行状态
指令执行状态包括:
- PENDING:等待执行
- RUNNING:正在执行
- COMPLETED:执行完成
- FAILED:执行失败
- SKIPPED:跳过执行
- TIMEOUT:执行超时
6. 指令依赖关系
6.1 依赖类型
指令之间的依赖关系可分为以下类型:
6.1.1 执行依赖
一个指令的执行依赖于另一个指令的完成。
{
"instructionId": "inst_2", // 指令2的唯一标识
"action": "process_data", // 指令动作:处理数据
"dependencies": ["inst_1"], // 依赖指令1完成后才能执行
"condition": "dependencies.inst_1.status == 'COMPLETED'" // 条件:指令1必须成功完成
}
6.1.2 数据依赖
一个指令的输入依赖于另一个指令的输出。
{
"instructionId": "inst_2", // 指令2的唯一标识
"action": "analyze_data", // 指令动作:分析数据
"parameters": {
"data": "${dependencies.inst_1.result.data}", // 使用指令1的结果数据作为输入
"threshold": 0.75, // 分析阈值
"method": "statistical" // 分析方法
},
"dependencies": ["inst_1"] // 依赖指令1,以获取其结果数据
}
6.1.3 条件依赖
一个指令的执行条件依赖于另一个指令的结果。
{
"instructionId": "inst_2", // 指令2的唯一标识
"action": "send_notification", // 指令动作:发送通知
"parameters": {
"message": "检测到异常数据", // 通知消息
"channel": "email", // 通知渠道
"priority": "high", // 优先级
"recipients": ["admin@example.com"] // 接收者
},
"dependencies": ["inst_1"], // 依赖指令1的结果
"condition": "dependencies.inst_1.result.anomaly_detected == true" // 条件:只有检测到异常才发送通知
}
JavaScript实现示例
以下是使用JavaScript实现条件依赖处理的示例代码:
/**
* 指令处理器 - JavaScript实现
* 处理指令间的依赖关系和条件执行
*/
class InstructionProcessor {
constructor() {
// 存储指令执行结果
this.instructionResults = new Map();
// 存储待处理指令
this.pendingInstructions = new Map();
}
/**
* 注册指令
* @param {Object} instruction 指令对象
*/
registerInstruction(instruction) {
this.pendingInstructions.set(instruction.instructionId, instruction);
}
/**
* 评估指令条件是否满足
* @param {Object} instruction 指令对象
* @returns {boolean} 条件是否满足
*/
evaluateCondition(instruction) {
// 如果没有条件,默认满足
if (!instruction.condition) {
return true;
}
// 如果有依赖但依赖结果不完整,返回false
if (instruction.dependencies && instruction.dependencies.length > 0) {
for (const depId of instruction.dependencies) {
if (!this.instructionResults.has(depId)) {
return false;
}
}
}
// 构建依赖对象用于条件评估
const dependencies = {};
if (instruction.dependencies) {
for (const depId of instruction.dependencies) {
dependencies[depId] = this.instructionResults.get(depId);
}
}
// 评估条件表达式
// 注意:实际实现应使用安全的表达式求值方法,这里简化处理
try {
// 将条件字符串转换为函数并执行
// 例如: "dependencies.inst_1.result.anomaly_detected == true"
// 安全的函数构造方式(实际项目中应使用专门的表达式求值库)
const conditionFunc = new Function('dependencies', `
try {
return ${instruction.condition};
} catch (e) {
console.error('条件评估错误:', e);
return false;
}
`);
return conditionFunc(dependencies);
} catch (error) {
console.error('条件评估出错:', error);
return false;
}
}
/**
* 执行指令
* @param {string} instructionId 指令ID
* @returns {Promise<Object>} 执行结果
*/
async executeInstruction(instructionId) {
const instruction = this.pendingInstructions.get(instructionId);
if (!instruction) {
throw new Error(`指令不存在: ${instructionId}`);
}
// 检查依赖是否已完成
if (instruction.dependencies && instruction.dependencies.length > 0) {
for (const depId of instruction.dependencies) {
if (!this.instructionResults.has(depId)) {
throw new Error(`依赖指令尚未完成: ${depId}`);
}
}
}
// 评估条件
const conditionMet = this.evaluateCondition(instruction);
if (!conditionMet) {
const result = {
status: 'SKIPPED',
reason: '条件不满足',
instructionId: instruction.instructionId
};
this.instructionResults.set(instructionId, result);
return result;
}
// 执行指令(实际实现根据action类型有不同处理)
try {
const result = await this.performAction(instruction);
this.instructionResults.set(instructionId, {
status: 'COMPLETED',
result: result,
instructionId: instruction.instructionId
});
return this.instructionResults.get(instructionId);
} catch (error) {
const result = {
status: 'FAILED',
error: error.message,
instructionId: instruction.instructionId
};
this.instructionResults.set(instructionId, result);
return result;
}
}
/**
* 执行指令的具体动作
* @param {Object} instruction 指令对象
* @returns {Promise<Object>} 执行结果
*/
async performAction(instruction) {
// 这里根据不同的action类型执行不同操作
// 例如发送通知的实现
if (instruction.action === 'send_notification') {
// 获取参数
const { message, channel, priority, recipients } = instruction.parameters;
// 实际发送通知的逻辑
console.log(`发送${priority}优先级通知到${channel}: ${message}`);
// 返回结果
return {
sent: true,
timestamp: new Date().toISOString(),
recipients: recipients
};
}
// 检测异常的实现示例
if (instruction.action === 'detect_anomaly') {
// 获取参数
const { data, threshold } = instruction.parameters;
// 模拟异常检测
console.log(`执行异常检测,阈值: ${threshold}`);
// 返回结果
return {
anomaly_detected: true, // 模拟检测到异常
confidence: 0.92,
anomalies: ["数据点#28超出范围"]
};
}
// 不支持的action类型
throw new Error(`不支持的action类型: ${instruction.action}`);
}
/**
* 按依赖顺序执行一组指令
* @param {Array<Object>} instructions 指令对象数组
* @returns {Promise<Object>} 执行结果映射
*/
async executeInstructions(instructions) {
// 注册所有指令
for (const instruction of instructions) {
this.registerInstruction(instruction);
}
// 创建依赖图
const dependencyGraph = new Map();
for (const instruction of instructions) {
dependencyGraph.set(
instruction.instructionId,
instruction.dependencies || []
);
}
// 计算执行顺序(拓扑排序)
const executionOrder = this.topologicalSort(dependencyGraph);
// 按顺序执行
for (const instructionId of executionOrder) {
await this.executeInstruction(instructionId);
}
return Object.fromEntries(this.instructionResults);
}
/**
* 依赖图的拓扑排序
* @param {Map<string, Array<string>>} graph 依赖图
* @returns {Array<string>} 执行顺序
*/
topologicalSort(graph) {
const visited = new Set();
const temp = new Set();
const order = [];
// 定义DFS函数
const dfs = (node) => {
if (temp.has(node)) {
throw new Error('检测到循环依赖');
}
if (!visited.has(node)) {
temp.add(node);
const neighbors = graph.get(node) || [];
for (const neighbor of neighbors) {
dfs(neighbor);
}
temp.delete(node);
visited.add(node);
order.push(node);
}
};
// 对每个节点执行DFS
for (const node of graph.keys()) {
if (!visited.has(node)) {
dfs(node);
}
}
return order.reverse();
}
}
// 使用示例
async function runExample() {
// 创建处理器
const processor = new InstructionProcessor();
// 定义指令列表
const instructions = [
{
instructionId: "inst_1",
action: "detect_anomaly",
parameters: {
data: [/* 数据集 */],
threshold: 0.8
}
},
{
instructionId: "inst_2",
action: "send_notification",
parameters: {
message: "检测到异常数据",
channel: "email",
priority: "high",
recipients: ["admin@example.com"]
},
dependencies: ["inst_1"],
condition: "dependencies.inst_1.result.anomaly_detected == true"
}
];
// 手动设置第一个指令的结果(实际应通过executeInstructions调用)
processor.instructionResults.set("inst_1", {
status: 'COMPLETED',
result: {
anomaly_detected: true,
confidence: 0.92,
anomalies: [/* 检测到的异常列表 */]
},
instructionId: "inst_1"
});
// 执行第二个指令
const result = await processor.executeInstruction("inst_2");
console.log("指令执行结果:", result);
/* 输出:
* 发送high优先级通知到email: 检测到异常数据
* 指令执行结果: {
* status: 'COMPLETED',
* result: {
* sent: true,
* timestamp: '2025-12-01T12:34:56.789Z',
* recipients: ['admin@example.com']
* },
* instructionId: 'inst_2'
* }
*/
}
// 运行示例
runExample().catch(console.error);
Java实现示例
以下是使用Java实现条件依赖处理的示例代码:
import java.time.Instant;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 指令处理器 - Java实现
* 处理指令间的依赖关系和条件执行
*/
public class InstructionProcessor {
// 存储指令执行结果
private final Map<String, InstructionResult> instructionResults = new HashMap<>();
// 存储待处理指令
private final Map<String, Instruction> pendingInstructions = new HashMap<>();
/**
* 指令类,表示待执行的操作
*/
public static class Instruction {
private final String instructionId;
private final String action;
private final Map<String, Object> parameters;
private final List<String> dependencies;
private final String condition;
public Instruction(String instructionId, String action, Map<String, Object> parameters,
List<String> dependencies, String condition) {
this.instructionId = instructionId;
this.action = action;
this.parameters = parameters;
this.dependencies = dependencies != null ? dependencies : Collections.emptyList();
this.condition = condition;
}
// Getters
public String getInstructionId() { return instructionId; }
public String getAction() { return action; }
public Map<String, Object> getParameters() { return parameters; }
public List<String> getDependencies() { return dependencies; }
public String getCondition() { return condition; }
}
/**
* 指令执行结果类
*/
public static class InstructionResult {
private final String status; // COMPLETED, FAILED, SKIPPED
private final Map<String, Object> result;
private final String error;
private final String instructionId;
private InstructionResult(String status, Map<String, Object> result, String error, String instructionId) {
this.status = status;
this.result = result;
this.error = error;
this.instructionId = instructionId;
}
// 创建成功结果
public static InstructionResult completed(String instructionId, Map<String, Object> result) {
return new InstructionResult("COMPLETED", result, null, instructionId);
}
// 创建失败结果
public static InstructionResult failed(String instructionId, String error) {
return new InstructionResult("FAILED", null, error, instructionId);
}
// 创建跳过结果
public static InstructionResult skipped(String instructionId, String reason) {
Map<String, Object> result = new HashMap<>();
result.put("reason", reason);
return new InstructionResult("SKIPPED", result, null, instructionId);
}
// Getters
public String getStatus() { return status; }
public Map<String, Object> getResult() { return result; }
public String getError() { return error; }
public String getInstructionId() { return instructionId; }
}
/**
* 注册指令
* @param instruction 指令对象
*/
public void registerInstruction(Instruction instruction) {
pendingInstructions.put(instruction.getInstructionId(), instruction);
}
/**
* 评估指令条件是否满足
* @param instruction 指令对象
* @return 条件是否满足
*/
public boolean evaluateCondition(Instruction instruction) {
// 如果没有条件,默认满足
if (instruction.getCondition() == null || instruction.getCondition().isEmpty()) {
return true;
}
// 如果有依赖但依赖结果不完整,返回false
for (String depId : instruction.getDependencies()) {
if (!instructionResults.containsKey(depId)) {
return false;
}
}
// 构建依赖对象用于条件评估
Map<String, InstructionResult> dependencies = new HashMap<>();
for (String depId : instruction.getDependencies()) {
dependencies.put(depId, instructionResults.get(depId));
}
// 评估条件表达式
// 在Java中,我们需要解析表达式并手动评估
// 这里使用简化的方法,实际项目应使用表达式引擎如MVEL, SpEL等
return evaluateExpressionSimple(instruction.getCondition(), dependencies);
}
/**
* 简化的表达式求值(仅支持基本比较)
* 实际项目中应使用成熟的表达式引擎
*/
private boolean evaluateExpressionSimple(String expression, Map<String, InstructionResult> dependencies) {
try {
// 简化:仅支持形如 "dependencies.inst_1.result.anomaly_detected == true" 的表达式
Pattern pattern = Pattern.compile("dependencies\\.(\\w+)\\.result\\.(\\w+)\\s*(==|!=|>|<|>=|<=)\\s*(.+)");
Matcher matcher = pattern.matcher(expression);
if (matcher.find()) {
String depId = matcher.group(1);
String property = matcher.group(2);
String operator = matcher.group(3);
String valueStr = matcher.group(4).trim();
// 获取依赖结果
InstructionResult dependency = dependencies.get(depId);
if (dependency == null || !"COMPLETED".equals(dependency.getStatus())) {
return false;
}
// 获取属性值
Object propertyValue = dependency.getResult().get(property);
if (propertyValue == null) {
return false;
}
// 解析比较值
Object compareValue;
if ("true".equals(valueStr) || "false".equals(valueStr)) {
compareValue = Boolean.parseBoolean(valueStr);
} else if (valueStr.matches("\\d+")) {
compareValue = Integer.parseInt(valueStr);
} else if (valueStr.matches("\\d+\\.\\d+")) {
compareValue = Double.parseDouble(valueStr);
} else {
// 去除引号处理字符串
compareValue = valueStr.replaceAll("^[\"']|[\"']$", "");
}
// 执行比较
if ("==".equals(operator)) {
return Objects.equals(propertyValue, compareValue);
} else if ("!=".equals(operator)) {
return !Objects.equals(propertyValue, compareValue);
} else if (">".equals(operator)) {
if (propertyValue instanceof Number && compareValue instanceof Number) {
return ((Number) propertyValue).doubleValue() > ((Number) compareValue).doubleValue();
}
} else if ("<".equals(operator)) {
if (propertyValue instanceof Number && compareValue instanceof Number) {
return ((Number) propertyValue).doubleValue() < ((Number) compareValue).doubleValue();
}
} else if (">=".equals(operator)) {
if (propertyValue instanceof Number && compareValue instanceof Number) {
return ((Number) propertyValue).doubleValue() >= ((Number) compareValue).doubleValue();
}
} else if ("<=".equals(operator)) {
if (propertyValue instanceof Number && compareValue instanceof Number) {
return ((Number) propertyValue).doubleValue() <= ((Number) compareValue).doubleValue();
}
}
}
// 默认返回false
return false;
} catch (Exception e) {
System.err.println("条件评估错误: " + e.getMessage());
return false;
}
}
/**
* 执行指令
* @param instructionId 指令ID
* @return 执行结果
* @throws Exception 如果执行过程中出错
*/
public CompletableFuture<InstructionResult> executeInstruction(String instructionId) {
return CompletableFuture.supplyAsync(() -> {
try {
Instruction instruction = pendingInstructions.get(instructionId);
if (instruction == null) {
throw new IllegalArgumentException("指令不存在: " + instructionId);
}
// 检查依赖是否已完成
for (String depId : instruction.getDependencies()) {
if (!instructionResults.containsKey(depId)) {
throw new IllegalStateException("依赖指令尚未完成: " + depId);
}
}
// 评估条件
boolean conditionMet = evaluateCondition(instruction);
if (!conditionMet) {
InstructionResult result = InstructionResult.skipped(
instruction.getInstructionId(), "条件不满足");
instructionResults.put(instructionId, result);
return result;
}
// 执行指令
InstructionResult result = performAction(instruction);
instructionResults.put(instructionId, result);
return result;
} catch (Exception e) {
InstructionResult result = InstructionResult.failed(instructionId, e.getMessage());
instructionResults.put(instructionId, result);
return result;
}
});
}
/**
* 执行指令的具体动作
* @param instruction 指令对象
* @return 执行结果
*/
private InstructionResult performAction(Instruction instruction) {
// 根据不同的action类型执行不同操作
// 例如发送通知的实现
if ("send_notification".equals(instruction.getAction())) {
Map<String, Object> parameters = instruction.getParameters();
// 获取参数
String message = (String) parameters.get("message");
String channel = (String) parameters.get("channel");
String priority = (String) parameters.get("priority");
@SuppressWarnings("unchecked")
List<String> recipients = (List<String>) parameters.get("recipients");
// 实际发送通知的逻辑
System.out.printf("发送%s优先级通知到%s: %s%n", priority, channel, message);
// 返回结果
Map<String, Object> result = new HashMap<>();
result.put("sent", true);
result.put("timestamp", Instant.now().toString());
result.put("recipients", recipients);
return InstructionResult.completed(instruction.getInstructionId(), result);
}
// 检测异常的实现示例
if ("detect_anomaly".equals(instruction.getAction())) {
Map<String, Object> parameters = instruction.getParameters();
// 获取参数
@SuppressWarnings("unchecked")
List<Object> data = (List<Object>) parameters.get("data");
double threshold = ((Number) parameters.get("threshold")).doubleValue();
// 模拟异常检测
System.out.println("执行异常检测,阈值: " + threshold);
// 返回结果
Map<String, Object> result = new HashMap<>();
result.put("anomaly_detected", true); // 模拟检测到异常
result.put("confidence", 0.92);
result.put("anomalies", Collections.singletonList("数据点#28超出范围"));
return InstructionResult.completed(instruction.getInstructionId(), result);
}
// 不支持的action类型
return InstructionResult.failed(
instruction.getInstructionId(),
"不支持的action类型: " + instruction.getAction()
);
}
/**
* 按依赖顺序执行一组指令
* @param instructions 指令对象列表
* @return 执行结果映射
* @throws Exception 如果执行过程中出错
*/
public CompletableFuture<Map<String, InstructionResult>> executeInstructions(List<Instruction> instructions) {
// 注册所有指令
for (Instruction instruction : instructions) {
registerInstruction(instruction);
}
// 创建依赖图
Map<String, List<String>> dependencyGraph = new HashMap<>();
for (Instruction instruction : instructions) {
dependencyGraph.put(
instruction.getInstructionId(),
instruction.getDependencies()
);
}
// 计算执行顺序(拓扑排序)
List<String> executionOrder;
try {
executionOrder = topologicalSort(dependencyGraph);
} catch (Exception e) {
return CompletableFuture.failedFuture(e);
}
// 按顺序执行
CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
for (String instructionId : executionOrder) {
future = future.thenCompose(v -> executeInstruction(instructionId)).thenApply(result -> null);
}
return future.thenApply(v -> new HashMap<>(instructionResults));
}
/**
* 依赖图的拓扑排序
* @param graph 依赖图
* @return 执行顺序
* @throws Exception 如果检测到循环依赖
*/
private List<String> topologicalSort(Map<String, List<String>> graph) throws Exception {
Set<String> visited = new HashSet<>();
Set<String> temp = new HashSet<>();
List<String> order = new ArrayList<>();
// 定义DFS函数
Function<String, Void> dfs = new Function<String, Void>() {
@Override
public Void apply(String node) {
if (temp.contains(node)) {
throw new RuntimeException("检测到循环依赖");
}
if (!visited.contains(node)) {
temp.add(node);
List<String> neighbors = graph.getOrDefault(node, Collections.emptyList());
for (String neighbor : neighbors) {
apply(neighbor);
}
temp.remove(node);
visited.add(node);
order.add(node);
}
return null;
}
};
// 对每个节点执行DFS
for (String node : graph.keySet()) {
if (!visited.contains(node)) {
dfs.apply(node);
}
}
// 反转结果
Collections.reverse(order);
return order;
}
/**
* 使用示例
*/
public static void main(String[] args) {
// 创建处理器
InstructionProcessor processor = new InstructionProcessor();
// 定义数据集参数(简化)
List<Object> dataSet = new ArrayList<>();
// 创建第一个指令:检测异常
Map<String, Object> params1 = new HashMap<>();
params1.put("data", dataSet);
params1.put("threshold", 0.8);
Instruction inst1 = new Instruction(
"inst_1", // 指令ID
"detect_anomaly", // 动作
params1, // 参数
Collections.emptyList(), // 无依赖
null // 无条件
);
// 创建第二个指令:发送通知
Map<String, Object> params2 = new HashMap<>();
params2.put("message", "检测到异常数据");
params2.put("channel", "email");
params2.put("priority", "high");
params2.put("recipients", Collections.singletonList("admin@example.com"));
Instruction inst2 = new Instruction(
"inst_2", // 指令ID
"send_notification", // 动作
params2, // 参数
Collections.singletonList("inst_1"), // 依赖指令1
"dependencies.inst_1.result.anomaly_detected == true" // 条件表达式
);
// 执行指令并获取结果
try {
// 注册并执行指令1
processor.registerInstruction(inst1);
InstructionResult result1 = processor.executeInstruction("inst_1").get();
System.out.println("指令1执行结果: " + result1.getStatus());
// 执行指令2
processor.registerInstruction(inst2);
InstructionResult result2 = processor.executeInstruction("inst_2").get();
System.out.println("指令2执行结果: " + result2.getStatus());
/* 输出:
* 执行异常检测,阈值: 0.8
* 指令1执行结果: COMPLETED
* 发送high优先级通知到email: 检测到异常数据
* 指令2执行结果: COMPLETED
*/
} catch (Exception e) {
e.printStackTrace();
}
}
}
6.2 依赖表达式
依赖条件可以使用表达式语法,支持以下操作:
- 逻辑操作:
AND
、OR
、NOT
- 比较操作:
==
、!=
、>
、<
、>=
、<=
- 属性访问:使用点号(.)访问对象属性
- 函数调用:
contains()
、isEmpty()
等
{
"condition": "dependencies.inst_1.status == 'COMPLETED' AND dependencies.inst_1.result.score > 0.8"
}
JavaScript实现示例
以下是使用JavaScript实现依赖表达式解析和评估的示例代码:
/**
* 依赖表达式解析器 - JavaScript实现
* 用于解析和评估复杂的依赖条件表达式
*/
class ExpressionEvaluator {
/**
* 评估依赖表达式
* @param {string} expression 条件表达式
* @param {Object} context 评估上下文,包含依赖指令的执行结果
* @returns {boolean} 表达式评估结果
*/
static evaluate(expression, context) {
// 安全评估函数
try {
return ExpressionEvaluator.parseAndEvaluate(expression, context);
} catch (error) {
console.error(`表达式评估出错: ${error.message}`);
return false;
}
}
/**
* 解析并评估简单表达式
* @param {string} expression 条件表达式
* @param {Object} context 评估上下文
* @returns {boolean} 评估结果
*/
static parseAndEvaluate(expression, context) {
// 处理AND表达式
if (expression.includes(" AND ")) {
const [left, right] = expression.split(" AND ");
return ExpressionEvaluator.parseAndEvaluate(left, context) &&
ExpressionEvaluator.parseAndEvaluate(right, context);
}
// 处理OR表达式
if (expression.includes(" OR ")) {
const [left, right] = expression.split(" OR ");
return ExpressionEvaluator.parseAndEvaluate(left, context) ||
ExpressionEvaluator.parseAndEvaluate(right, context);
}
// 处理NOT表达式
if (expression.startsWith("NOT ")) {
const subExpr = expression.substring(4);
return !ExpressionEvaluator.parseAndEvaluate(subExpr, context);
}
// 处理括号表达式
if (expression.startsWith("(") && expression.endsWith(")")) {
const subExpr = expression.substring(1, expression.length - 1);
return ExpressionEvaluator.parseAndEvaluate(subExpr, context);
}
// 处理基本比较表达式
return ExpressionEvaluator.evaluateComparison(expression, context);
}
/**
* 评估比较表达式
* @param {string} expression 比较表达式
* @param {Object} context 评估上下文
* @returns {boolean} 比较结果
*/
static evaluateComparison(expression, context) {
// 解析比较表达式 "path operator value"
const matches = expression.match(/([^\s]+)\s*(==|!=|>|<|>=|<=)\s*(.+)/);
if (!matches) {
throw new Error(`无效的比较表达式: ${expression}`);
}
const [_, leftPath, operator, rightValueStr] = matches;
// 解析左侧路径值
const leftValue = ExpressionEvaluator.resolvePathValue(leftPath, context);
// 解析右侧值
let rightValue;
if (rightValueStr.startsWith("'") && rightValueStr.endsWith("'")) {
// 字符串字面量
rightValue = rightValueStr.substring(1, rightValueStr.length - 1);
} else if (rightValueStr === 'true' || rightValueStr === 'false') {
// 布尔字面量
rightValue = rightValueStr === 'true';
} else if (!isNaN(Number(rightValueStr))) {
// 数字字面量
rightValue = Number(rightValueStr);
} else {
// 可能是另一个路径
rightValue = ExpressionEvaluator.resolvePathValue(rightValueStr, context);
}
// 执行比较
switch (operator) {
case '==': return leftValue == rightValue;
case '!=': return leftValue != rightValue;
case '>': return leftValue > rightValue;
case '<': return leftValue < rightValue;
case '>=': return leftValue >= rightValue;
case '<=': return leftValue <= rightValue;
default: throw new Error(`未知的操作符: ${operator}`);
}
}
/**
* 从对象中解析路径值
* @param {string} path 属性路径,如 "dependencies.inst_1.result.score"
* @param {Object} obj 要查询的对象
* @returns {any} 解析的值
*/
static resolvePathValue(path, obj) {
if (!path || !obj) return undefined;
const parts = path.split('.');
let current = obj;
for (const part of parts) {
if (current === null || current === undefined) {
return undefined;
}
current = current[part];
}
return current;
}
/**
* 内置函数: 检查数组是否包含特定值
*/
static contains(array, value) {
return Array.isArray(array) && array.includes(value);
}
/**
* 内置函数: 检查字符串/数组/对象是否为空
*/
static isEmpty(value) {
if (value === null || value === undefined) return true;
if (typeof value === 'string') return value.trim().length === 0;
if (Array.isArray(value)) return value.length === 0;
if (typeof value === 'object') return Object.keys(value).length === 0;
return false;
}
}
// 使用示例
function testExpressionEvaluation() {
// 创建依赖上下文
const context = {
dependencies: {
inst_1: {
status: 'COMPLETED',
result: {
score: 0.92,
items: ['apple', 'banana', 'orange'],
metadata: {
source: 'primary',
confidence: 'high'
}
}
},
inst_2: {
status: 'COMPLETED',
result: {
count: 5,
threshold: 0.75
}
}
}
};
// 测试各种表达式
console.log('简单表达式:');
const expr1 = "dependencies.inst_1.status == 'COMPLETED'";
console.log(`${expr1} => ${ExpressionEvaluator.evaluate(expr1, context)}`);
console.log('\nAND表达式:');
const expr2 = "dependencies.inst_1.status == 'COMPLETED' AND dependencies.inst_1.result.score > 0.8";
console.log(`${expr2} => ${ExpressionEvaluator.evaluate(expr2, context)}`);
console.log('\nOR表达式:');
const expr3 = "dependencies.inst_1.result.score < 0.5 OR dependencies.inst_2.result.count > 3";
console.log(`${expr3} => ${ExpressionEvaluator.evaluate(expr3, context)}`);
console.log('\n复杂表达式:');
const expr4 = "(dependencies.inst_1.status == 'COMPLETED' AND dependencies.inst_1.result.score > 0.8) OR (dependencies.inst_2.status == 'FAILED')";
console.log(`${expr4} => ${ExpressionEvaluator.evaluate(expr4, context)}`);
/* 输出:
* 简单表达式:
* dependencies.inst_1.status == 'COMPLETED' => true
*
* AND表达式:
* dependencies.inst_1.status == 'COMPLETED' AND dependencies.inst_1.result.score > 0.8 => true
*
* OR表达式:
* dependencies.inst_1.result.score < 0.5 OR dependencies.inst_2.result.count > 3 => true
*
* 复杂表达式:
* (dependencies.inst_1.status == 'COMPLETED' AND dependencies.inst_1.result.score > 0.8) OR (dependencies.inst_2.status == 'FAILED') => true
*/
}
// 执行测试
testExpressionEvaluation();
6.3 依赖循环检测
系统必须检测并拒绝执行存在循环依赖的指令集。循环依赖的定义为:指令A直接或间接依赖于指令B,同时指令B直接或间接依赖于指令A。
6.4 依赖可视化
复杂的依赖关系可以表示为有向无环图(DAG),其中节点为指令,边为依赖关系。
7. 错误处理机制
7.1 错误类型
通讯过程中可能出现以下错误类型:
- 解析错误:消息格式不符合规范
- 验证错误:消息内容未通过验证
- 执行错误:工具或指令执行失败
- 超时错误:执行超过预定时间
- 依赖错误:依赖的指令或工具调用失败
- 系统错误:系统内部错误
7.2 错误响应格式
错误响应应遵循以下格式:
{
"type": "ERROR_RESPONSE", // 消息类型:错误响应
"content": {
"errorCode": "AUTH_FAILED", // 错误代码,标识错误类型
"message": "认证失败,无法访问请求的资源", // 用户友好的错误描述
"details": { // 详细错误信息对象
"requestId": "req_789xyz", // 相关请求ID
"timestamp": "2025-12-01T12:34:56Z", // 错误发生时间
"traceId": "trace_abc123", // 跟踪ID,用于日志关联
"violatedPolicies": ["rate_limit", "ip_restriction"] // 违反的策略
},
"source": "服务端", // 错误来源:客户端|服务端|工具|系统
"recoverable": true, // 是否可恢复的错误
"suggestedAction": "请稍后重试或减少请求频率" // 建议的修复操作
}
}
7.3 错误恢复策略
根据错误类型和可恢复性,可采取以下恢复策略:
- 重试:对于临时错误,可在一定延迟后重试
- 降级:当某功能不可用时,使用替代功能
- 部分结果:返回已成功处理的部分结果
- 跳过:跳过失败的步骤,继续执行后续步骤
- 终止:对于严重错误,终止整个处理流程
8. 上下文状态管理
8.1 上下文结构
上下文是对话或交互的状态容器,包含以下信息:
{
"contextId": "ctx_abcdefg", // 上下文唯一标识
"creationTime": "2025-12-01T10:00:00Z", // 创建时间
"lastUpdateTime": "2025-12-01T10:05:00Z", // 最后更新时间
"messages": [ // 消息历史数组
{
"messageId": "msg_001", // 第一条消息
"type": "USER_INPUT",
"content": {
"text": "你好"
}
},
{
"messageId": "msg_002", // 第二条消息
"type": "MODEL_RESPONSE",
"content": {
"text": "您好!有什么可以帮助您的?"
}
}
],
"state": { // 上下文状态对象
"currentTopic": "天气查询", // 当前对话主题
"userPreferences": { // 用户偏好设置
"language": "中文", // 语言偏好
"timezone": "Asia/Shanghai" // 时区设置
},
"activeTools": ["weather_api", "calculator"], // 当前活跃的工具列表
"customState": { // 自定义状态数据
"lastSearchLocation": "北京", // 上次搜索的位置
"searchCount": 3 // 搜索次数统计
}
},
"metadata": { // 元数据
"userId": "user_123", // 用户ID
"sessionId": "session_456", // 会话ID
"clientInfo": { // 客户端信息
"device": "smartphone", // 设备类型
"platform": "iOS", // 平台
"version": "15.4", // 版本
"ipAddress": "192.168.1.1" // IP地址
}
}
}
8.2 状态更新操作
上下文状态可以通过以下操作更新:
8.2.1 添加消息
将新消息添加到上下文历史。
{
"type": "CONTEXT_UPDATE",
"content": {
"operation": "ADD_MESSAGE",
"message": {
// 消息对象
}
}
}
8.2.2 更新状态
更新上下文状态的特定字段。
{
"type": "CONTEXT_UPDATE",
"content": {
"operation": "UPDATE_STATE",
"path": "userPreferences.language",
"value": "英文"
}
}
8.2.3 清除历史
清除部分或全部历史消息。
{
"type": "CONTEXT_UPDATE",
"content": {
"operation": "CLEAR_HISTORY",
"filter": {
"beforeTimestamp": "2025-12-01T09:00:00Z"
}
}
}
8.3 状态同步
多客户端场景下,上下文状态需要同步,可通过以下机制实现:
- 版本号:每次更新增加版本号
- 时间戳:使用更新时间戳判断最新状态
- 变更日志:记录每次变更,用于合并冲突
9. 通讯示例
9.1 简单工具调用示例
用户查询天气的对话流程
- 用户输入消息:
{
"messageId": "msg_001", // 消息唯一标识
"contextId": "ctx_weather", // 上下文ID,关联到天气查询对话
"timestamp": "2025-12-01T10:00:00Z", // 消息时间戳
"type": "USER_INPUT", // 消息类型:用户输入
"sender": {
"id": "user_123", // 用户ID
"type": "USER" // 发送者类型:用户
},
"content": {
"text": "北京今天天气怎么样?" // 用户询问的文本内容
}
}
- 模型响应,请求调用天气工具:
{
"messageId": "msg_002", // 消息唯一标识
"contextId": "ctx_weather", // 关联的上下文ID
"timestamp": "2025-12-01T10:00:01Z", // 消息时间戳
"type": "MODEL_RESPONSE", // 消息类型:模型响应
"sender": {
"id": "model_gpt4", // 模型ID
"type": "MODEL" // 发送者类型:模型
},
"content": {
"text": "我需要查询一下北京的天气信息。", // 模型生成的文本
"toolCalls": [ // 模型请求的工具调用
{
"callId": "call_001", // 调用唯一标识
"name": "weather_api", // 工具名称:天气API
"parameters": {
"city": "北京", // 查询参数:城市
"date": "2025-12-01" // 查询参数:日期
}
}
],
"finishReason": "TOOL_CALLS" // 生成结束原因:需要调用工具
}
}
- 系统执行工具调用并返回结果:
{
"messageId": "msg_003", // 消息唯一标识
"contextId": "ctx_weather", // 关联的上下文ID
"timestamp": "2025-12-01T10:00:02Z", // 消息时间戳
"type": "TOOL_CALL_RESPONSE", // 消息类型:工具调用响应
"sender": {
"id": "system", // 发送者ID:系统
"type": "SYSTEM" // 发送者类型:系统
},
"content": {
"results": [ // 工具调用结果数组
{
"callId": "call_001", // 对应的调用ID
"status": "SUCCESS", // 执行状态:成功
"result": { // 结果数据
"city": "北京", // 城市名称
"date": "2025-12-01", // 日期
"temperature": "5°C", // 温度
"weather": "晴", // 天气状况
"wind": "北风3级", // 风力风向
"humidity": "30%" // 湿度
},
"executionTime": 500 // 执行耗时(毫秒)
}
]
}
}
- 模型根据工具调用结果生成最终回复:
{
"messageId": "msg_004", // 消息唯一标识
"contextId": "ctx_weather", // 关联的上下文ID
"timestamp": "2025-12-01T10:00:03Z", // 消息时间戳
"type": "MODEL_RESPONSE", // 消息类型:模型响应
"sender": {
"id": "model_gpt4", // 模型ID
"type": "MODEL" // 发送者类型:模型
},
"content": {
"text": "北京今天天气晴朗,气温5°C,北风3级,湿度30%。今天天气不错,但温度较低,外出时建议穿厚一点的衣服。", // 模型基于天气数据生成的回复
"finishReason": "STOP" // 生成结束原因:自然结束
}
}
9.2 多指令依赖示例
用户请求生成并分析数据的复杂流程
- 用户输入请求生成并分析销售数据:
{
"messageId": "msg_101", // 消息唯一标识
"contextId": "ctx_sales", // 上下文ID,关联到销售数据分析
"timestamp": "2025-12-01T14:00:00Z", // 消息时间戳
"type": "USER_INPUT", // 消息类型:用户输入
"sender": {
"id": "user_456", // 用户ID
"type": "USER" // 发送者类型:用户
},
"content": {
"text": "请生成过去30天的销售数据,并分析销售趋势,最后生成一个报告摘要。" // 用户复杂请求
}
}
- 系统创建指令集,包含多个依赖关系的指令:
{
"messageId": "msg_102", // 消息唯一标识
"contextId": "ctx_sales", // 关联的上下文ID
"timestamp": "2025-12-01T14:00:01Z", // 消息时间戳
"type": "INSTRUCTION", // 消息类型:指令消息
"sender": {
"id": "system", // 发送者ID:系统
"type": "SYSTEM" // 发送者类型:系统
},
"content": {
"instructions": [ // 指令数组,包含多个连续指令
{
"instructionId": "inst_101", // 第一个指令:查询数据
"action": "QUERY_DATA", // 动作:查询数据
"parameters": {
"query": "SELECT date, product_id, quantity, price FROM sales WHERE date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)", // SQL查询语句
"limit": 1000 // 结果限制
}
},
{
"instructionId": "inst_102", // 第二个指令:处理数据
"action": "PROCESS_DATA", // 动作:处理数据
"parameters": {
"data": "${dependencies.inst_101.result.data}", // 使用第一个指令的结果
"operations": [ // 要执行的操作列表
"aggregate_by_date", // 按日期聚合
"calculate_daily_revenue" // 计算日收入
]
},
"dependencies": ["inst_101"], // 依赖第一个指令
"condition": "dependencies.inst_101.status == 'COMPLETED'" // 条件:第一个指令必须完成
},
{
"instructionId": "inst_103", // 第三个指令:分析趋势
"action": "ANALYZE_TREND", // 动作:分析趋势
"parameters": {
"data": "${dependencies.inst_102.result.processed_data}", // 使用第二个指令的结果
"metrics": [ // 分析指标列表
"daily_revenue", // 每日收入
"product_distribution" // 产品分布
],
"timeRange": "30d" // 时间范围:30天
},
"dependencies": ["inst_102"], // 依赖第二个指令
"condition": "dependencies.inst_102.status == 'COMPLETED'" // 条件:第二个指令必须完成
},
{
"instructionId": "inst_104", // 第四个指令:生成报告
"action": "GENERATE_REPORT", // 动作:生成报告
"parameters": {
"rawData": "${dependencies.inst_101.result.data}", // 使用原始数据
"processedData": "${dependencies.inst_102.result.processed_data}", // 使用处理后的数据
"analysis": "${dependencies.inst_103.result.analysis}", // 使用分析结果
"format": "markdown", // 报告格式:Markdown
"sections": [ // 报告包含的章节
"summary", // 摘要
"trends", // 趋势
"recommendations" // 建议
]
},
"dependencies": ["inst_101", "inst_102", "inst_103"], // 依赖前三个指令
"condition": "dependencies.inst_103.status == 'COMPLETED'" // 条件:第三个指令必须完成
}
],
"executionMode": "SEQUENTIAL", // 执行模式:顺序执行
"timeout": 120 // 整体超时时间:120秒
}
}
- 系统依次执行指令并返回最终结果(简化展示):
{
"messageId": "msg_103", // 消息唯一标识
"contextId": "ctx_sales", // 关联的上下文ID
"timestamp": "2025-12-01T14:00:30Z", // 消息时间戳
"type": "MODEL_RESPONSE", // 消息类型:模型响应
"sender": {
"id": "model_gpt4", // 模型ID
"type": "MODEL" // 发送者类型:模型
},
"content": {
"text": "# 销售数据分析报告\n\n## 摘要\n过去30天的销售总额为¥1,250,000,同比增长15.3%。\n\n## 主要趋势\n- 周末销售额平均比工作日高出23%\n- 电子产品类别增长最快,达到22.5%\n- 促销活动期间销售额提升了31.2%\n\n## 建议\n1. 增加周末促销力度,特别是电子产品类别\n2. 优化低销售时段的库存管理\n3. 根据趋势预测,提前备货即将到来的季节性需求\n\n详细数据和图表可以在完整报告中查看。", // 模型基于分析结果生成的报告
"finishReason": "STOP" // 生成结束原因:自然结束
}
}
10. 安全与性能
10.1 安全考虑
通讯过程中应注意以下安全事项:
- 数据加密:所有传输的数据应使用TLS加密
- 身份验证:确保通讯双方身份的合法性
- 授权控制:根据身份和权限控制访问
- 敏感信息处理:敏感信息应脱敏或加密存储
- 输入验证:验证所有输入数据,防止注入攻击
- 安全日志:记录关键操作和异常情况
10.2 性能优化
为提高通讯效率,可采取以下优化措施:
- 消息压缩:压缩大型消息内容
- 增量更新:只传输变化的部分
- 批量处理:将多个小请求合并处理
- 缓存:缓存频繁使用的数据
- 预加载:预先加载可能需要的资源
- 异步处理:对非关键操作使用异步处理
10.3 扩展性设计
协议设计考虑了未来扩展的需求:
- 版本控制:通过版本号支持协议演进
- 扩展字段:预留metadata字段用于扩展
- 向后兼容:新版本应兼容旧版本客户端
- 插件机制:支持添加新的消息类型和处理逻辑
- 自定义属性:允许添加自定义属性和行为
版本历史
版本 | 日期 | 变更说明 |
---|---|---|
1.0.0 | 2025-03-15 | 初始版本 |
版权所有 © 2025 尹周志