为什么是 5W2H + PDCA:所有可执行工作的通用框架
1.1 结构化执行的两大支柱
Gliding Horse Agent OS 建立在两个通用框架之上,它们是处理任何任务的基础:
-
5W2H(What-做什么、Why-为什么、Who-谁做、When-何时、Where-何地、How-怎么做、How Much-多少资源) --- 任务本体
- 回答:"到底需要做什么?"
- 目的:明确意图、约束和成功标准
- 时机:在任务初始化阶段应用
-
PDCA 循环(Plan-计划、Do-执行、Check-检查、Act-改进) --- 执行模型
- 回答:"我们如何系统地执行和改进?"
- 目的:提供带持续反馈的迭代执行
- 时机:贯穿任务生命周期
专业模型(技能扩展)
通用框架(始终必需)
基础
流程
可选技能
可选技能
可选技能
可选技能
5W2H
━━━━━━━━
任务本体
明确要做什么
PDCA 循环
━━━━━━━━
执行模型
定义如何执行
SWOT 分析
战略定位
5 Whys
根因分析
SMART 目标
目标细化
看板
工作流可视化
可执行任务
为什么两者缺一不可:
任何可执行任务 = 5W2H(意图清晰度)+ PDCA(系统性执行)
| 框架 | 角色 | 缺少它会怎样 |
|---|---|---|
| 5W2H | 定义做什么 | 目标模糊 → 期望偏离 |
| PDCA | 定义如何迭代执行 | 混乱实施 → 缺乏质量控制 |
完整工作流:
ActAgentCheckAgentDoAgentPlanAgentSupervisorAgentUserActAgentCheckAgentDoAgentPlanAgentSupervisorAgentUser步骤 1:提取 5W2H(What/Why/Who/When/Where/How/HowMuch)提交任务请求执行 PLAN 阶段生成微流程 DAG返回执行计划执行 DO 阶段调用工具,写入产物返回实施结果执行 CHECK 阶段按 5W2H 维度审计返回审计裁决执行 ACT 阶段决策:通过/回滚/终止最终决定交付结果 + 归档
1.2 5W2H:任务本体
5W2H 捕捉了任何可执行工作的完整本质。如果你无法清晰阐述所有 7 个维度,任务本质上是不可执行的。
为什么 5W2H 不可替代:
| 维度 | 回答的问题 | 缺失的后果 |
|---|---|---|
| What(做什么) | 需要做什么? | 无清晰目标 → 盲目执行 |
| Why(为什么) | 为什么重要? | 无动机/优先级 → 低参与度 |
| Who(谁做) | 谁负责? | 问责缺失 → 无人负责 |
| When(何时) | 必须何时完成? | 无截止日期 → 永远拖延 |
| Where(何地) | 在哪里执行? | 上下文模糊 → 错误环境 |
| How(怎么做) | 如何执行? | 无方法 → 混乱实施 |
| How Much(多少资源) | 可用资源? | 预算超支 → 项目失败 |
任一维度的模糊性都会导致:
- 干系人之间的期望不一致
- 资源配置不当(时间、预算、人员)
- 无法衡量成功或失败
- 审计失败和问责缺失
1.3 PDCA:通用化执行模型
与传统管理型 PDCA 不同,Gliding Horse 实现了通用化计算型 PDCA,能够适应任务复杂度:
七个复杂度级别:
| 级别 | 类型 | PDCA 适配 | 示例 |
|---|---|---|---|
| L0 | 即时任务 | 单轮,无需 PDCA | "现在几点?" |
| L1 | 简单任务 | 单次 PDCA 循环 | "写一个 Python 脚本" |
| L2 | 标准任务 | 完整 PDCA + 结构化审计 | "分析 Q2 销售数据" |
| L3 | 复杂项目 | 多智能体并行 Do 阶段 | "构建 REST API + 测试" |
| L4 | 探索型任务 | 多 DA 并行,不同策略 | "研究最佳技术栈" |
| L5 | 递归任务 | 子任务生成子 PDCA 循环 | "重构整个代码库" |
| L6 | 紧急模式 | 跳过 Plan,立即 Do-Check | "立即修复生产 Bug" |
关键创新 :Supervisor Agent 根据 5W2H 元数据分析动态选择合适的 PDCA 模式,而非僵化的模板。这使得同一个编排引擎既能处理简单的查询,也能处理持续数周的工程项目。
1.4 专业模型作为技能扩展
在 Gliding Horse Agent OS 中,SWOT、5 Whys、SMART 等专业模型被实现为技能图谱系统中的可复用技能。当 5W2H 元数据表明适用时,它们被调用:
{
"task:5W2H": {
"what": "分析市场竞争",
"why": "识别战略定位机会",
"how": {
"preferredSkills": ["skill:swot-analysis", "skill:porter-five-forces"]
}
}
}
此设计确保:
- 一致性:每个任务都有相同的结构基础(5W2H + PDCA)
- 可扩展性:专业分析方法作为可插拔技能
- 可审计性:CA 可独立验证每个维度
- 模式识别:具有类似 5W2H 配置的历史任务触发相关技能推荐
2. JSON-LD 简化用法:连接 LLM 与知识图谱
2.1 挑战
LLM 不擅长生成复杂的 JSON-LD 结构。它们擅长生成自然语言和简单的 JSON 对象。然而,系统需要 JSON-LD 来实现:
- 全局实体标识(
@id) - 语义类型(
@type) - 字段名规范化(
@context) - 深度控制以管理 Token 预算
2.2 我们的解决方案:Harness 引擎混合方案
我们使用一个翻译层(Harness Engine),将简单的 LLM 输出转换为 JSON-LD 节点:
存储层
Harness 引擎处理
LLM 输出(简单 JSON)
按需加载
{
'think': 'Planning...',
'contents': 'CREATE TABLE...',
'summary': 'Schema designed'
}
Harness Engine
━━━━━━━━
-
按 JSON Schema 验证
-
转换为 JSON-LD 节点
-
分配 @id
-
写入 L0 存储
L0 持久存储
━━━━━━━━
redb KV + HyperspaceEngine
全保真归档
L2 Oxigraph 内存
━━━━━━━━
内存 RDF
快速查询 ~2ms
2.3 LLM 响应结构(针对存储效率优化)
{
"think": "Analyzing user request for database schema design...",
"contents": "CREATE TABLE users (id UUID PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL);",
"summary": "Database schema for user table with UUID primary key and unique email constraint"
}
为什么采用三字段结构?
| 字段 | 用途 | 存储策略 | 检索模式 |
|---|---|---|---|
| think | 思维链推理 | 归档至 L0 | 调试 / 可追溯性 |
| contents | 完整详细输出 | 归档至 L0 | 缺页故障时加载 |
| summary | 简洁摘要 | 索引至 L2 | 快速上下文概览 |
存储与检索机制:
步骤 1: LLM 生成 think/contents/summary
→ 三个字段均以 @id: "memory:session-001/block-042" 归档至 L0
→ summary 同时在 L2 中建立索引以快速访问
步骤 2: Agent 需要下一轮上下文
→ L2 返回 summary(~50 tokens)作为轻量级上下文
→ L1 上下文窗口保持小巧
步骤 3: 用户要求查看详情("显示完整的 SQL")
→ 系统检测到需要完整内容
→ 触发"缺页故障":通过 IRI 引用从 L0 加载 contents
→ 返回完整 SQL 语句
结果:L1/L2 保持精简,L0 保存全保真,通过 IRI 按需加载
类比 CPU 虚拟内存:
| 概念 | CPU 架构 | Gliding Horse 内存 |
|---|---|---|
| 工作集 | RAM(快速、有限) | L2 Oxigraph(快速,~2ms) |
| 页表 | 虚拟→物理映射 | IRI 引用 |
| 缺页故障 | 磁盘 → RAM 加载 | L0 → L2 加载 |
| 交换空间 | 磁盘存储 | L0 redb + HyperspaceEngine |
此设计实现了:
- ✅ 性能:L2 内存查询延迟 ~2ms
- ✅ 可扩展性:L0 磁盘存储,容量无限
- ✅ Token 经济性:基于摘要的 L1/L2 上下文,Token 使用最小化
- ✅ 可追溯性:think/contents 完整保留于 L0 供调试
- ✅ 互操作性:JSON-LD 支持跨智能体数据共享
2.4 Harness 引擎的角色
Harness 引擎充当了以下两者之间的翻译层:
- LLM 的舒适区:包含 think/contents/summary 的简单 JSON
- 系统的需求:包含 @id、@type、@context 的 JSON-LD,用于互操作
处理流程:
// 说明转换过程的伪代码
let llm_output = llm_client.generate(prompt).await?; // 返回简单 JSON
// 步骤 1:按 JSON Schema 验证
validation_engine.validate(&llm_output.contents, &skill.input_schema)?;
// 步骤 2:转换为 JSON-LD 节点
let jsonld_node = json!({
"@id": format!("memory:{}/block-{}", session_id, block_counter),
"@type": ["mem:MemoryBlock", "exec:TaskResult"],
"mem:think": llm_output.think,
"mem:contents": llm_output.contents,
"mem:summary": llm_output.summary,
"mem:embedding": embedding_service.index(&llm_output.contents).await?
});
// 步骤 3:写入 L0 持久存储(全保真归档)
l0_manager.insert_node(&jsonld_node)?;
// 步骤 4:在 L2 中建立摘要索引以便快速访问
l2_manager.index_summary(&jsonld_node["@id"], &llm_output.summary)?;
此设计分离了关注点:
- L0:全保真归档(think + contents + summary)
- L2:快速访问工作集(summary + 元数据)
- L1:活跃上下文窗口(仅摘要,受 Token 约束)
2.5 实战代码示例:Python 调用 Harness 引擎
下面是一个完整的 Python 示例,展示如何将 LLM 的简单 JSON 输出转换为符合系统规范的 JSON-LD 节点,并写入存储层。代码包含详细的注释和错误处理。
"""
harness_client.py --- Gliding Horse Harness 引擎 Python 客户端示例
功能:接收 LLM 的 think/contents/summary 输出,转换为 JSON-LD 节点,
执行 Schema 校验,并写入 L0 持久存储与 L2 索引。
"""
import json
import uuid
import hashlib
import logging
from datetime import datetime, timezone
from typing import Optional, TypedDict
# 配置日志
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
# ──────────────────────────────────────────────
# 1. 类型定义
# ──────────────────────────────────────────────
class LLMOutput(TypedDict, total=False):
"""LLM 输出的标准三字段结构"""
think: str # 思维链推理过程
contents: str # 完整详细输出
summary: str # 简洁摘要(用于 L2 索引)
class JSONLDNode(TypedDict, total=False):
"""转换后的 JSON-LD 节点"""
"@id": str
"@type": list[str]
"@context": dict
"mem:think": str
"mem:contents": str
"mem:summary": str
"mem:embedding": Optional[list[float]]
"mem:createdAt": str
# ──────────────────────────────────────────────
# 2. Schema 校验器
# ──────────────────────────────────────────────
class SchemaValidator:
"""
模拟 JSON Schema 校验器。
生产环境可替换为 jsonschema 库或 SHACL 引擎。
"""
REQUIRED_FIELDS = {"think", "contents", "summary"}
@classmethod
def validate(cls, data: dict, schema_name: str = "default") -> bool:
"""
校验 LLM 输出是否符合基本 Schema。
Args:
data: LLM 输出的字典
schema_name: Schema 名称(预留扩展)
Returns:
True 通过校验,否则抛出 ValueError
Raises:
ValueError: 缺少必填字段或字段类型错误
"""
# 检查必填字段
missing = cls.REQUIRED_FIELDS - set(data.keys())
if missing:
raise ValueError(f"Schema 校验失败,缺少字段: {missing}")
# 检查字段类型
for field in cls.REQUIRED_FIELDS:
if not isinstance(data.get(field), str):
raise ValueError(
f"Schema 校验失败,字段 '{field}' 应为字符串,"
f"实际类型: {type(data.get(field)).__name__}"
)
# 检查字段长度(防止空字符串)
for field in cls.REQUIRED_FIELDS:
if not data[field].strip():
raise ValueError(f"Schema 校验失败,字段 '{field}' 为空")
logger.info("Schema 校验通过 (schema=%s)", schema_name)
return True
# ──────────────────────────────────────────────
# 3. 嵌入服务(模拟)
# ──────────────────────────────────────────────
class EmbeddingService:
"""模拟向量嵌入服务,生产环境可替换为 OpenAI/text2vec 等"""
@staticmethod
async def index(text: str) -> list[float]:
"""
生成文本的向量嵌入。
此处用文本的 SHA-256 哈希的前 16 字节模拟嵌入向量,
仅作演示用途。生产环境应调用真实的嵌入模型。
"""
hash_bytes = hashlib.sha256(text.encode("utf-8")).digest()[:16]
embedding = [b / 255.0 for b in hash_bytes] # 归一化到 [0, 1]
logger.debug("生成嵌入向量,维度=%d", len(embedding))
return embedding
# ──────────────────────────────────────────────
# 4. 存储管理器(模拟)
# ──────────────────────────────────────────────
class L0StorageManager:
"""模拟 L0 持久存储(redb KV + HyperspaceEngine)"""
def __init__(self):
self._store: dict[str, dict] = {}
async def insert_node(self, node: dict) -> str:
"""
将 JSON-LD 节点写入 L0 存储。
Args:
node: 完整的 JSON-LD 节点字典
Returns:
节点的 @id
"""
node_id = node.get("@id", "unknown")
self._store[node_id] = node
logger.info("L0 存储: 已写入节点 %s (大小: %d bytes)",
node_id, len(json.dumps(node, ensure_ascii=False)))
return node_id
def get_node(self, node_id: str) -> Optional[dict]:
"""按 @id 读取节点"""
return self._store.get(node_id)
class L2IndexManager:
"""模拟 L2 内存索引(Oxigraph 摘要索引)"""
def __init__(self):
self._index: dict[str, str] = {}
async def index_summary(self, node_id: str, summary: str) -> None:
"""
在 L2 中建立摘要索引。
Args:
node_id: 节点的 @id
summary: 摘要文本
"""
self._index[node_id] = summary
logger.info("L2 索引: 已索引节点 %s (摘要长度: %d chars)",
node_id, len(summary))
def search_by_summary(self, keyword: str) -> list[str]:
"""按关键词搜索摘要(演示用)"""
return [
nid for nid, summary in self._index.items()
if keyword.lower() in summary.lower()
]
# ──────────────────────────────────────────────
# 5. Harness 引擎核心
# ──────────────────────────────────────────────
class HarnessEngine:
"""
Harness 引擎:LLM 简单 JSON → JSON-LD 节点的翻译层。
职责:
1. 校验 LLM 输出是否符合 Schema
2. 分配全局唯一 @id
3. 构建 JSON-LD 节点(含 @type、@context)
4. 生成向量嵌入
5. 写入 L0 持久存储
6. 在 L2 中建立摘要索引
"""
# JSON-LD 上下文定义(可扩展)
DEFAULT_CONTEXT = {
"@vocab": "https://agent-harness.os/memory#",
"mem": "https://agent-harness.os/memory#",
"exec": "https://agent-harness.os/execution#",
"xsd": "http://www.w3.org/2001/XMLSchema#",
}
def __init__(
self,
session_id: str,
validator: Optional[SchemaValidator] = None,
embedding_service: Optional[EmbeddingService] = None,
l0_manager: Optional[L0StorageManager] = None,
l2_manager: Optional[L2IndexManager] = None,
):
self.session_id = session_id
self.block_counter = 0
self.validator = validator or SchemaValidator()
self.embedding_service = embedding_service or EmbeddingService()
self.l0_manager = l0_manager or L0StorageManager()
self.l2_manager = l2_manager or L2IndexManager()
async def process_llm_output(self, llm_output: LLMOutput) -> JSONLDNode:
"""
处理 LLM 输出,返回完整的 JSON-LD 节点。
Args:
llm_output: LLM 输出的三字段字典
Returns:
转换后的 JSON-LD 节点
Raises:
ValueError: Schema 校验失败
RuntimeError: 存储写入失败
"""
# 步骤 1:Schema 校验
try:
self.validator.validate(llm_output, schema_name="llm_output_v1")
except ValueError as e:
logger.error("LLM 输出校验失败: %s", e)
raise
# 步骤 2:分配 @id
self.block_counter += 1
node_id = f"memory:{self.session_id}/block-{self.block_counter:03d}"
# 步骤 3:生成向量嵌入
try:
embedding = await self.embedding_service.index(llm_output["contents"])
except Exception as e:
logger.warning("嵌入生成失败,跳过: %s", e)
embedding = None
# 步骤 4:构建 JSON-LD 节点
now = datetime.now(timezone.utc).isoformat()
jsonld_node: JSONLDNode = {
"@id": node_id,
"@type": ["mem:MemoryBlock", "exec:TaskResult"],
"@context": self.DEFAULT_CONTEXT,
"mem:think": llm_output["think"],
"mem:contents": llm_output["contents"],
"mem:summary": llm_output["summary"],
"mem:createdAt": now,
}
if embedding is not None:
jsonld_node["mem:embedding"] = embedding
# 步骤 5:写入 L0 持久存储
try:
await self.l0_manager.insert_node(jsonld_node)
except Exception as e:
raise RuntimeError(f"L0 写入失败: {e}") from e
# 步骤 6:在 L2 中建立摘要索引
try:
await self.l2_manager.index_summary(node_id, llm_output["summary"])
except Exception as e:
logger.warning("L2 索引失败(不影响主流程): %s", e)
logger.info("Harness 处理完成: %s", node_id)
return jsonld_node
# ──────────────────────────────────────────────
# 6. 使用示例
# ──────────────────────────────────────────────
async def main():
"""演示 Harness 引擎的完整工作流程"""
# 初始化引擎
engine = HarnessEngine(
session_id=f"session-{uuid.uuid4().hex[:8]}",
validator=SchemaValidator(),
embedding_service=EmbeddingService(),
l0_manager=L0StorageManager(),
l2_manager=L2IndexManager(),
)
# 模拟 LLM 输出
llm_response: LLMOutput = {
"think": (
"用户请求设计数据库 Schema。"
"分析需求:需要用户表,包含 UUID 主键和唯一邮箱约束。"
"选择 PostgreSQL 作为目标数据库。"
),
"contents": (
"CREATE TABLE users (\n"
" id UUID PRIMARY KEY,\n"
" email VARCHAR(255) UNIQUE NOT NULL,\n"
" created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n"
");"
),
"summary": "为用户表设计了 PostgreSQL Schema,包含 UUID 主键和唯一邮箱约束",
}
print("=" * 60)
print("Harness 引擎实战演示")
print("=" * 60)
# 步骤 1:处理 LLM 输出
print("\n[1] 接收 LLM 输出:")
print(json.dumps(llm_response, ensure_ascii=False, indent=2))
try:
node = await engine.process_llm_output(llm_response)
except (ValueError, RuntimeError) as e:
print(f"\n[错误] 处理失败: {e}")
return
# 步骤 2:查看转换后的 JSON-LD 节点
print("\n[2] 转换后的 JSON-LD 节点:")
print(json.dumps(node, ensure_ascii=False, indent=2, default=str))
# 步骤 3:验证存储
print("\n[3] 验证存储:")
stored = engine.l0_manager.get_node(node["@id"])
if stored:
print(f" ✅ L0 存储: 节点 {node['@id']} 已持久化")
else:
print(f" ❌ L0 存储: 节点未找到")
# 步骤 4:验证 L2 索引
print("\n[4] L2 索引搜索 ('用户表'):")
results = engine.l2_manager.search_by_summary("用户表")
if results:
for rid in results:
print(f" ✅ 找到: {rid}")
else:
print(" ⚠️ 未找到匹配(关键词不精确)")
# 步骤 5:错误处理演示
print("\n[5] 错误处理演示 --- 传入空字段:")
try:
bad_input: LLMOutput = {"think": "", "contents": "some SQL", "summary": "test"}
await engine.process_llm_output(bad_input)
except ValueError as e:
print(f" ✅ 正确捕获错误: {e}")
print("\n" + "=" * 60)
print("演示完成")
print("=" * 60)
# ──────────────────────────────────────────────
# 7. 入口
# ──────────────────────────────────────────────
if __name__ == "__main__":
import asyncio
asyncio.run(main())
代码要点说明:
| 模块 | 职责 | 关键设计 |
|---|---|---|
SchemaValidator |
校验 LLM 输出完整性 | 检查必填字段、类型、非空,可扩展为 jsonschema/SHACL |
EmbeddingService |
生成向量嵌入 | 演示用 SHA-256 模拟,生产环境替换为真实模型 |
L0StorageManager |
全保真持久存储 | 模拟 redb KV,支持按 @id 读写 |
L2IndexManager |
摘要快速索引 | 模拟 Oxigraph 内存索引,支持关键词搜索 |
HarnessEngine |
核心翻译层 | 串联校验→ID分配→嵌入→构建→存储→索引全流程 |
运行方式:
# 安装依赖(生产环境需额外安装 jsonschema、openai 等)
pip install aiohttp
# 运行示例
python harness_client.py
预期输出片段: