docs: add Chinese architecture brief with localized diagrams
Diagram generator takes a locale (en|zh) via a label dictionary; render.sh now emits img/ and img/zh/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bg6jx9vHNHzB91qyV64GQ7
68
docs/external/architecture-brief.zh.md
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# 虚拟电厂 AI 平台 — 系统架构
|
||||||
|
|
||||||
|
**基于光明电力大模型的虚拟电厂多时空协同智能运营平台**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
本平台是面向湖北虚拟电厂运营的 AI 协同决策与受控执行系统。五类 LLM 智能体生成市场申报、调度方案与负荷控制计划;任何对外效果产生之前,都必须经过一条确定性的可信执行链。三条设计承诺定义了整个架构:
|
||||||
|
|
||||||
|
- **两平面分离,唯一通道。** 慢速的认知平面(LLM 智能体,分钟到天)与快速的控制平面(确定性执行,秒级)严格分离,可信执行链是两者之间唯一的通道。
|
||||||
|
- **LLM 不算数。** 申报价格、电量与控制设定值只能来自版本化的预测、优化与仿真工具;Proposal 中的每一个数值字段都是对某次已记录工具调用的引用。
|
||||||
|
- **包络自治。** 人工审批的对象是包络(带有效期的边界授权),而不是每一笔动作。包络内的动作经规则校核与仿真验证后自动放行,其余一律升级人工。包络从空集起步,仅凭证据放宽。
|
||||||
|
|
||||||
|
## 1. 系统上下文
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
平台向上对接省级交易平台、调度/负荷管理系统与计量结算系统,向下聚合可调资源(现状 31 MW,目标不低于 80 MW)。运营人员通过运营工单台工作:每一项 AI 产出都挂在一张有明确目标、责任人和期限的工单之下。平台是既有 3060 平台之上的叠加层:复用主数据与权限体系,并把所有申报与控制动作收敛到唯一一条留痕通道,使任何动作都无法绕过可信执行链。
|
||||||
|
|
||||||
|
## 2. Agent Runtime
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
工作流才是入口,Agent 不是。每个业务流程(日前申报、复盘、日内纠偏)都是一条确定性、可持久化的步骤链,Agent 只在特定步骤被调用,并且只能使用白名单内的工具:产出数字的计算类 Skill,以及按需获取细节的只读检索工具。周期触发与事件触发直接实例化流程模板,全程不经过 LLM;只有人工请求经过路由 Agent,而路由 Agent 的输出被 schema 约束为「已注册模板 id + 参数」。LLM 决定「做什么」,工作流引擎决定「怎么做」。每一次触发、步骤、工具调用、状态迁移、审批与许可都写入事件溯源日志。
|
||||||
|
|
||||||
|
## 3. 上下文管理与记忆
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
每个 Agent 步骤的上下文由上游的确定性步骤组装:读取带版本号的账本、不可变快照、由模板显式声明的语义记忆,以及生效中的知识条目。Agent 不选择自己的基线上下文,因此每次决策都从可复现的起点出发。Agent 输出中的数字只能以对工具调用血缘的引用形式出现,由组装器解引用填值——这意味着 LLM 文本不可能把任何数字带进 Proposal。
|
||||||
|
|
||||||
|
上下文按**渐进式披露**构建。基线是精简的:摘要、标识符,以及该步骤所需的少量数字,按保守的上下文窗口设计。更多细节通过**智能体检索工具**按需披露:只读、白名单化的注册表工具,如规则检索、账本读取、快照获取、预测查询,Agent 在需要时可以调用。每次检索连同输入输出记录到血缘,因此「Agent 当时看到了什么」可以完整重放;提示注入防线把检索到的内容一律当作数据,而非指令。同一原则也贯穿运营界面:AI 结论卡片先给出结论,展开后才显示背后的工具输出与数据来源。
|
||||||
|
|
||||||
|
三层记忆各有不同的生命周期。工作记忆只存活于单个任务;情景记忆就是事件日志与时序库,永久保存,通过查询而非召回使用;语义记忆存放 D+1 复盘写回的结构化经验,版本化,并由各流程模板显式注入。运营事实的权威存储永远是领域数据库,而不是智能体记忆。
|
||||||
|
|
||||||
|
## 4. 可信执行链与状态机
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
一切拟执行动作都是一个 `Proposal`:带类型化载荷、完整血缘与不可变摘要。所有 Proposal 类型共用同一条生命周期工作流:
|
||||||
|
|
||||||
|
| 环节 | 内容 |
|
||||||
|
|---|---|
|
||||||
|
| 规则校核 | 确定性政策包:合规性、约束、账本一致性、血缘完整性、职责分离 |
|
||||||
|
| 仿真验证 | 申报类做收益回测,控制类做功率平衡;仿真告警一票升级人工 |
|
||||||
|
| 包络检查 | 落在已批准包络内:自动放行并完整留痕;否则工作流挂起,进入工单台审批收件箱 |
|
||||||
|
| 人工审批 | 由身份与发起链路分离的审批人恢复工作流;审批绑定摘要与有效窗口 |
|
||||||
|
| 现势复核 | 下发前即时重验:资源在线、约束仍满足、证据未变化;否则置为 `STALE` 重新走链 |
|
||||||
|
| 许可与放行 | 签发 `ExecutionPermit`:短时效、可吊销、摘要一致;网关只受理 `(Proposal, ExecutionPermit)` 对 |
|
||||||
|
|
||||||
|
挂起中的审批可跨进程重启存活。许可吊销是最快的回退手段:网关立即拒收后续指令,边缘终端退回上一批准计划或安全曲线。
|
||||||
|
|
||||||
|
## 5. 技术栈
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Runtime、智能体、工作流、领域 schema 与确定性服务均为 TypeScript + Mastra,看重的是类型化工具契约与持久化的挂起/恢复能力;专业模型 Skill 是 Python HTTP 服务。LLM 调用经由面向能力的抽象层与模型路由器,后端从开发期的商用 API、预生产的本地开源模型,切换到生产环境的光明电力大模型适配器,业务代码零改动。Runtime 还提供 LLM 不可用时的降级模式:预测、优化、校核、审批、申报与控制全部无需 LLM 即可运行。框架大约解决三分之一的问题,差异化资产是自建的确定性服务。
|
||||||
|
|
||||||
|
## 6. 接口与契约
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
手写的 zod schema 是唯一事实来源。构建时导出 JSON Schema 到入库的 contracts 目录,再据此生成 pydantic 模型,禁止手改。黄金样例(含正例与反例)由 TypeScript 与 Python 两端 CI 各自校验,任何结论不一致即构建失败。平台内部,每条信任边界都是一个 LLM 不可调用的端口:Proposal 提交、政策引擎、仿真、包络、授权、网关、账本、证据与工单台。数据表示纪律也是契约的一部分:金额与电量用定点小数字符串、单位编进字段名、UTC 时间戳、时段用日期加序号、全部 ID 为字符串、枚举全大写。
|
||||||
|
|
||||||
|
## 7. 评测驱动的开发过程
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
由于每个决策都能从留存证据完整重放,审计留痕本身就是评测数据集。四层评测对象用于定位问题:L1 LLM 任务,L2 专业模型 Skill,L3 可信执行链正确性(每条不变式至少一个自动化测试),L4 通过影子运行与历史回测衡量的端到端决策质量。评测就是变更门禁:提示词变更须通过 L1 任务集与 L4 回测;后端切换须通过 L1 全集与 L4 影子对比;Skill 升版必须在同一次变更中更新其已提交的 L2 基线;政策包升版须规则测试全绿;包络放宽仅凭 L4 影子或在线数据审批。每条复盘结论都会成为候选评测用例,失败案例持续喂养下一版基线。
|
||||||
25
docs/external/diagrams/gen.mjs
vendored
@ -1,16 +1,23 @@
|
|||||||
import { writeFileSync } from 'node:fs'
|
import { writeFileSync } from 'node:fs'
|
||||||
|
import zh from './zh.mjs'
|
||||||
|
|
||||||
|
// usage: node gen.mjs <outdir> [en|zh]
|
||||||
|
const LOCALE = process.argv[3] || 'en'
|
||||||
|
const T = (s) => (LOCALE === 'zh' ? (zh[s] ?? s) : s)
|
||||||
|
// approximate rendered width: CJK glyphs are ~1em, Latin ~0.55em
|
||||||
|
const tw = (s, size) => [...s].reduce((w, ch) => w + (/[\u3000-\u9fff\uff00-\uffef]/.test(ch) ? size * 1.0 : size * 0.55), 0)
|
||||||
|
|
||||||
const C = {
|
const C = {
|
||||||
ink: '#1B2331', ink2: '#4A5568', ink3: '#7A8494', line: '#B9C2CE',
|
ink: '#1B2331', ink2: '#4A5568', ink3: '#7A8494', line: '#B9C2CE',
|
||||||
teal: '#2C6B70', tealSoft: '#E4F0F0', amber: '#B86A14', amberSoft: '#F7ECDD',
|
teal: '#2C6B70', tealSoft: '#E4F0F0', amber: '#B86A14', amberSoft: '#F7ECDD',
|
||||||
slate: '#EEF1F5', red: '#A23B3B', redSoft: '#F6E3E3', white: '#FFFFFF',
|
slate: '#EEF1F5', red: '#A23B3B', redSoft: '#F6E3E3', white: '#FFFFFF',
|
||||||
}
|
}
|
||||||
const FONT = 'font-family="Helvetica Neue,Helvetica,Arial,sans-serif"'
|
const FONT = 'font-family="Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Arial,sans-serif"'
|
||||||
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
||||||
|
|
||||||
function text(x, y, s, { size = 13, fill = C.ink, anchor = 'middle', weight = 400, mono = false, italic = false } = {}) {
|
function text(x, y, s, { size = 13, fill = C.ink, anchor = 'middle', weight = 400, mono = false, italic = false } = {}) {
|
||||||
const fam = mono ? 'font-family="Menlo,SFMono-Regular,Consolas,monospace"' : ''
|
const fam = mono ? 'font-family="Menlo,SFMono-Regular,Consolas,PingFang SC,monospace"' : ''
|
||||||
return `<text x="${x}" y="${y}" ${fam} font-size="${size}" fill="${fill}" text-anchor="${anchor}" font-weight="${weight}"${italic ? ' font-style="italic"' : ''}>${esc(s)}</text>`
|
return `<text x="${x}" y="${y}" ${fam} font-size="${size}" fill="${fill}" text-anchor="${anchor}" font-weight="${weight}"${italic ? ' font-style="italic"' : ''}>${esc(T(s))}</text>`
|
||||||
}
|
}
|
||||||
// title + sub lines centered in box
|
// title + sub lines centered in box
|
||||||
function box(x, y, w, h, title, sub = [], o = {}) {
|
function box(x, y, w, h, title, sub = [], o = {}) {
|
||||||
@ -23,15 +30,15 @@ function box(x, y, w, h, title, sub = [], o = {}) {
|
|||||||
s += text(x + w / 2, cy, title, { size: tsize, fill: tcolor, weight: 600, mono })
|
s += text(x + w / 2, cy, title, { size: tsize, fill: tcolor, weight: 600, mono })
|
||||||
for (const l of sub) { cy += lh; s += text(x + w / 2, cy, l, { size: ssize, fill: scolor }) }
|
for (const l of sub) { cy += lh; s += text(x + w / 2, cy, l, { size: ssize, fill: scolor }) }
|
||||||
if (tag) {
|
if (tag) {
|
||||||
const tw = tag.length * 7 + 14
|
const tagw = tw(T(tag), 10) * 1.15 + 14
|
||||||
s += `<rect x="${x + w - tw - 6}" y="${y - 9}" width="${tw}" height="18" rx="9" fill="${tagColor}"/>` + text(x + w - tw / 2 - 6, y + 4, tag, { size: 10, fill: C.white, weight: 700 })
|
s += `<rect x="${x + w - tagw - 6}" y="${y - 9}" width="${tagw}" height="18" rx="9" fill="${tagColor}"/>` + text(x + w - tagw / 2 - 6, y + 4, tag, { size: 10, fill: C.white, weight: 700 })
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
function group(x, y, w, h, label, o = {}) {
|
function group(x, y, w, h, label, o = {}) {
|
||||||
const { stroke = C.line, fill = 'none', color = C.ink3 } = o
|
const { stroke = C.line, fill = 'none', color = C.ink3 } = o
|
||||||
return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="8" fill="${fill}" stroke="${stroke}" stroke-width="1" stroke-dasharray="5 4"/>` +
|
return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="8" fill="${fill}" stroke="${stroke}" stroke-width="1" stroke-dasharray="5 4"/>` +
|
||||||
text(x + 12, y + 18, label.toUpperCase(), { size: 10.5, fill: color, anchor: 'start', weight: 700 })
|
text(x + 12, y + 18, LOCALE === 'zh' ? label : label.toUpperCase(), { size: LOCALE === 'zh' ? 11.5 : 10.5, fill: color, anchor: 'start', weight: 700 })
|
||||||
}
|
}
|
||||||
function arrow(x1, y1, x2, y2, label = '', o = {}) {
|
function arrow(x1, y1, x2, y2, label = '', o = {}) {
|
||||||
const { dashed = false, both = false, color = C.ink2, lx = 0, ly = -6, path = null, lsize = 11.5, lfill = C.ink2 } = o
|
const { dashed = false, both = false, color = C.ink2, lx = 0, ly = -6, path = null, lsize = 11.5, lfill = C.ink2 } = o
|
||||||
@ -39,8 +46,8 @@ function arrow(x1, y1, x2, y2, label = '', o = {}) {
|
|||||||
let s = `<path d="${d}" fill="none" stroke="${color}" stroke-width="1.4"${dashed ? ' stroke-dasharray="5 4"' : ''} marker-end="url(#ah)"${both ? ' marker-start="url(#ahs)"' : ''}/>`
|
let s = `<path d="${d}" fill="none" stroke="${color}" stroke-width="1.4"${dashed ? ' stroke-dasharray="5 4"' : ''} marker-end="url(#ah)"${both ? ' marker-start="url(#ahs)"' : ''}/>`
|
||||||
if (label) {
|
if (label) {
|
||||||
const mx = (x1 + x2) / 2 + lx, my = (y1 + y2) / 2 + ly
|
const mx = (x1 + x2) / 2 + lx, my = (y1 + y2) / 2 + ly
|
||||||
const tw = label.length * 6.4 + 8
|
const lw = tw(T(label), lsize) + 8
|
||||||
s += `<rect x="${mx - tw / 2}" y="${my - 10}" width="${tw}" height="15" fill="${C.white}" opacity=".92"/>` + text(mx, my + 2, label, { size: lsize, fill: lfill })
|
s += `<rect x="${mx - lw / 2}" y="${my - 10}" width="${lw}" height="15" fill="${C.white}" opacity=".92"/>` + text(mx, my + 2, label, { size: lsize, fill: lfill })
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@ -83,7 +90,7 @@ const out = {}
|
|||||||
b += box(980, 360, 190, 80, 'Flexible resources', ['PV · storage · EV charging', 'HVAC · industrial · microgrids'], { fill: C.white })
|
b += box(980, 360, 190, 80, 'Flexible resources', ['PV · storage · EV charging', 'HVAC · industrial · microgrids'], { fill: C.white })
|
||||||
b += arrow(630, 440, 630, 465)
|
b += arrow(630, 440, 630, 465)
|
||||||
b += arrow(360, 400, 360, 140, '', { path: 'M360,400 L345,400 L345,140 L360,140', dashed: true })
|
b += arrow(360, 400, 360, 140, '', { path: 'M360,400 L345,400 L345,140 L360,140', dashed: true })
|
||||||
b += `<text transform="translate(340,330) rotate(-90)" font-size="10.5" fill="${C.ink2}" text-anchor="middle">execution feedback</text>`
|
b += `<text transform="translate(340,330) rotate(-90)" font-size="10.5" fill="${C.ink2}" text-anchor="middle">${T('execution feedback')}</text>`
|
||||||
b += text(1075, 470, '31 MW today → ≥ 80 MW target', { size: 11, fill: C.ink3 })
|
b += text(1075, 470, '31 MW today → ≥ 80 MW target', { size: 11, fill: C.ink3 })
|
||||||
out['01-system-context'] = svg(1200, 550, b)
|
out['01-system-context'] = svg(1200, 550, b)
|
||||||
}
|
}
|
||||||
|
|||||||
16
docs/external/diagrams/render.sh
vendored
@ -3,14 +3,18 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
CHROME="${CHROME:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}"
|
CHROME="${CHROME:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}"
|
||||||
tmp=$(mktemp -d)
|
for locale in en zh; do
|
||||||
node gen.mjs "$tmp" >/dev/null
|
out=../img; [ "$locale" = zh ] && out=../img/zh
|
||||||
for f in "$tmp"/*.html; do
|
mkdir -p "$out"
|
||||||
|
tmp=$(mktemp -d)
|
||||||
|
node gen.mjs "$tmp" "$locale" >/dev/null
|
||||||
|
for f in "$tmp"/*.html; do
|
||||||
n=$(basename "${f%.html}")
|
n=$(basename "${f%.html}")
|
||||||
dims=$(grep -o 'width="[0-9]*" height="[0-9]*" font' "$f" | head -1 | grep -o '[0-9]*' | tr '\n' ' ')
|
dims=$(grep -o 'width="[0-9]*" height="[0-9]*" font' "$f" | head -1 | grep -o '[0-9]*' | tr '\n' ' ')
|
||||||
set -- $dims
|
set -- $dims
|
||||||
"$CHROME" --headless=new --disable-gpu --hide-scrollbars --force-device-scale-factor=2 \
|
"$CHROME" --headless=new --disable-gpu --hide-scrollbars --force-device-scale-factor=2 \
|
||||||
--window-size="$1,$2" --screenshot="../img/$n.png" "$f" >/dev/null 2>&1
|
--window-size="$1,$2" --screenshot="$out/$n.png" "$f" >/dev/null 2>&1
|
||||||
|
done
|
||||||
|
rm -rf "$tmp"
|
||||||
done
|
done
|
||||||
rm -rf "$tmp"
|
ls ../img ../img/zh
|
||||||
ls ../img
|
|
||||||
|
|||||||
252
docs/external/diagrams/zh.mjs
vendored
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
// Chinese labels for the external diagrams. Keys are the English strings in gen.mjs.
|
||||||
|
// Code identifiers (state names, ports, tech names) are intentionally left untranslated.
|
||||||
|
export default {
|
||||||
|
// 01 system context
|
||||||
|
'External systems': '外部系统',
|
||||||
|
'Trading platform': '交易平台',
|
||||||
|
'bids · clearing · disclosures': '申报 · 出清 · 信息披露',
|
||||||
|
'Dispatch / load mgmt': '调度 / 负荷管理系统',
|
||||||
|
'regulation requests': '调节指令与需求',
|
||||||
|
'Metering / settlement': '计量结算系统',
|
||||||
|
'meter data · statements': '计量数据 · 结算单',
|
||||||
|
'Weather & market data': '气象与行情数据',
|
||||||
|
'read-only feeds': '只读数据源',
|
||||||
|
'VPP AI Platform': '虚拟电厂 AI 平台',
|
||||||
|
'Cognitive plane': '认知平面',
|
||||||
|
'five LLM agents · agent runtime · workflows': '五类 LLM 智能体 · Agent Runtime · 工作流',
|
||||||
|
'minutes to days': '分钟 ~ 天',
|
||||||
|
'Safety chain': '可信执行链',
|
||||||
|
'rule check → simulation → envelope / human approval → fresh check → permit': '规则校核 → 仿真验证 → 包络检查 / 人工审批 → 现势复核 → 执行许可',
|
||||||
|
'deterministic · the only path between planes': '确定性 · 两平面之间唯一通道',
|
||||||
|
'Control plane': '控制平面',
|
||||||
|
'execution engine · edge terminals · seconds': '执行引擎 · 边缘控制终端 · 秒级',
|
||||||
|
'Data foundation': '数据底座',
|
||||||
|
'time-series · relational · knowledge/vector · feature store · event log': '时序库 · 关系库 · 知识库/向量库 · 特征库 · 事件日志',
|
||||||
|
'Proposal (digest + lineage)': 'Proposal(摘要 + 血缘)',
|
||||||
|
'bid + permit': '申报 + 许可',
|
||||||
|
'Operators': '运营人员',
|
||||||
|
'Case Desk · approvals': '运营工单台 · 审批',
|
||||||
|
'scenario forks · AI cards': '情景分支 · AI 结论卡片',
|
||||||
|
'Flexible resources': '可调资源',
|
||||||
|
'PV · storage · EV charging': '光伏 · 储能 · 充电桩',
|
||||||
|
'HVAC · industrial · microgrids': '空调 · 工业负荷 · 微网园区',
|
||||||
|
'execution feedback': '执行反馈',
|
||||||
|
'31 MW today → ≥ 80 MW target': '现状 31 MW → 目标 ≥ 80 MW',
|
||||||
|
'LLM': 'LLM',
|
||||||
|
'NO LLM': '无 LLM',
|
||||||
|
|
||||||
|
// 02 agent runtime
|
||||||
|
'Task triggers': '任务触发',
|
||||||
|
'Scheduled': '周期触发',
|
||||||
|
'day-ahead 06:00 · bid window · D+1 review': '日前 06:00 · 申报窗口 · D+1 复盘',
|
||||||
|
'Event': '事件触发',
|
||||||
|
'deviation · resource offline · clearing': '偏差超阈 · 资源离线 · 出清',
|
||||||
|
'Manual': '人工触发',
|
||||||
|
'operator question or task': '运营人员提问或下达任务',
|
||||||
|
'Router agent': '路由 Agent',
|
||||||
|
'intent → template id + params': '意图 → 模板 id + 参数',
|
||||||
|
'schema-constrained enum': '输出受 schema 枚举约束',
|
||||||
|
'Workflow engine': '工作流引擎',
|
||||||
|
'deterministic step chains': '确定性步骤链',
|
||||||
|
'durable · suspend/resume': '持久化 · 可挂起/恢复',
|
||||||
|
'one template per business process': '每个业务流程一个模板',
|
||||||
|
'no LLM in the path': '路径上无 LLM',
|
||||||
|
'rule-matched': '规则匹配',
|
||||||
|
'Agent step': 'Agent 步骤',
|
||||||
|
'one of five agents, invoked at a step': '五类智能体之一,在特定步骤被调用',
|
||||||
|
'tools whitelisted per agent': '每个 Agent 的工具集为白名单',
|
||||||
|
'Tool registry': '工具注册表',
|
||||||
|
'typed, versioned skill contracts': '类型化、版本化的 Skill 契约',
|
||||||
|
'every call snapshotted into lineage': '每次调用快照写入血缘',
|
||||||
|
'Python skill services': 'Python Skill 服务',
|
||||||
|
'forecast · MILP · simulation': '预测 · MILP 优化 · 仿真',
|
||||||
|
'Proposal → safety chain': 'Proposal → 可信执行链',
|
||||||
|
'numbers dereferenced from lineage': '数字从血缘解引用取得',
|
||||||
|
'Event log (event-sourced): triggers, steps, tool calls, transitions, approvals, permits, receipts': '事件日志(事件溯源):触发、步骤、工具调用、状态迁移、审批、许可、回执',
|
||||||
|
'LLM involved': 'LLM 参与',
|
||||||
|
'Deterministic': '确定性',
|
||||||
|
'Workflows are the entry point, not agents. The LLM decides what to do (pick a template); the engine decides how, step by step.': '工作流才是入口,Agent 不是。LLM 决定「做什么」(选模板),工作流引擎决定「怎么按步骤做」。',
|
||||||
|
|
||||||
|
// 03 context & memory
|
||||||
|
'Context assembly for one agent step · deterministic baseline + progressive disclosure': '单个 Agent 步骤的上下文组装 · 确定性基线 + 渐进式披露',
|
||||||
|
'Position ledger': '持仓账本',
|
||||||
|
'versioned read': '带版本号读取',
|
||||||
|
'Time-series / snapshots': '时序库 / 快照',
|
||||||
|
'immutable, checksummed': '不可变、带校验和',
|
||||||
|
'Semantic memory': '语义记忆',
|
||||||
|
'lessons declared by template': '由流程模板显式声明注入的经验',
|
||||||
|
'Knowledge base (RAG)': '知识库(RAG)',
|
||||||
|
'effective rules only': '仅检索生效中的规则条目',
|
||||||
|
'fetchContext step (deterministic, reproducible)': 'fetchContext 步骤(确定性、可复现)',
|
||||||
|
'compact baseline: summaries, identifiers, the few figures a step needs': '精简基线:摘要、标识符,以及该步骤所需的少量数字',
|
||||||
|
'Agentic retrieval tools · read-only · whitelisted · every call logged into lineage': '智能体检索工具 · 只读 · 白名单 · 每次调用写入血缘',
|
||||||
|
'rule retrieval · ledger read · snapshot fetch · forecast lookup — detail disclosed on demand, retrieved content tagged as data': '规则检索 · 账本读取 · 快照获取 · 预测查询 —— 细节按需披露,检索内容标记为数据而非指令',
|
||||||
|
'prose + tool calls': '文字说明 + 工具调用',
|
||||||
|
'numbers only as': '数字只能以',
|
||||||
|
'{toolCallId, path}': '{toolCallId, path}',
|
||||||
|
'references': '引用形式出现',
|
||||||
|
'Assembler': '组装器',
|
||||||
|
'dereferences refs': '从血缘记录中',
|
||||||
|
'from recorded lineage': '解引用填值',
|
||||||
|
'→ Proposal': '→ Proposal',
|
||||||
|
'LLM text cannot': 'LLM 文本无法',
|
||||||
|
'carry a number': '带入任何数字',
|
||||||
|
'Three memory layers': '三层记忆',
|
||||||
|
'Working memory': '工作记忆',
|
||||||
|
'current task context, intermediate results': '当前任务上下文与中间结果',
|
||||||
|
'runtime memory · task lifetime': 'Runtime 内存 · 任务级生命周期',
|
||||||
|
'step-to-step parameters preferred over memory': '步骤间传参优先,能不进记忆就不进',
|
||||||
|
'Episodic memory': '情景记忆',
|
||||||
|
'operating states, trading, control, responses': '运行状态、交易、控制、用户响应',
|
||||||
|
'event log + time-series · permanent (audit)': '事件日志 + 时序库 · 永久保存(审计)',
|
||||||
|
'queried through fetchContext, not recalled': '经 fetchContext 确定性查询,不做自动召回',
|
||||||
|
'structured lessons from D+1 review': 'D+1 复盘沉淀的结构化经验',
|
||||||
|
'knowledge + strategy store · versioned': '知识库 + 策略库 · 版本化',
|
||||||
|
'written by ReviewFinding, injected explicitly': '由 ReviewFinding 写入,按模板显式注入',
|
||||||
|
'Authoritative facts live in the domain database, never in agent memory (invariant I8). No automatic memory recall feeds production decisions.': '运营事实的权威存储是领域数据库,而非智能体记忆(不变式 I8)。生产决策不依赖任何自动记忆召回。',
|
||||||
|
|
||||||
|
// 04 safety chain
|
||||||
|
'agent output': 'Agent 生成',
|
||||||
|
'policy pack': '政策包校核',
|
||||||
|
'backtest / balance': '收益回测 / 功率平衡',
|
||||||
|
'within bounds?': '是否在包络内',
|
||||||
|
'auto or human': '自动或人工',
|
||||||
|
're-verify state': '重验现势',
|
||||||
|
'permit issued': '签发执行许可',
|
||||||
|
'gateway accepts': '网关凭许可受理',
|
||||||
|
'Safety chain · deterministic · shared by every proposal type': '可信执行链 · 确定性 · 所有 Proposal 类型共用',
|
||||||
|
'suspended run · Case Desk inbox': '工作流挂起 · 进入工单台审批收件箱',
|
||||||
|
'outside envelope': '包络外',
|
||||||
|
'sim warning': '仿真告警',
|
||||||
|
'human resume': '人工裁决恢复',
|
||||||
|
'approver ≠ originator (I1)': '审批人 ≠ 发起链路(I1)',
|
||||||
|
'within envelope → AUTO_APPROVED': '包络内 → AUTO_APPROVED',
|
||||||
|
'rule failure': '规则不通过',
|
||||||
|
'human rejects': '人工驳回',
|
||||||
|
'evidence changed': '实质证据已变化',
|
||||||
|
're-enter chain': '重新走链',
|
||||||
|
'→ ExecutionReport → review': '→ ExecutionReport → 复盘',
|
||||||
|
'Approval binds to the proposal digest and a validity window (I3). Gateways accept only (Proposal, ExecutionPermit): short-lived, revocable, digest-matched (I4).': '审批绑定 Proposal 的不可变摘要与有效窗口(I3)。网关只受理 (Proposal, ExecutionPermit):短时效、可吊销、摘要一致(I4)。',
|
||||||
|
'Simulation warnings always escalate to a human. No code path lets the AI reach APPROVED. Envelopes start empty and widen only on shadow-run evidence.': '仿真告警一票升级人工。不存在任何让 AI 到达 APPROVED 的代码路径。包络从空集起步,仅凭影子运行证据放宽。',
|
||||||
|
|
||||||
|
// 05 tech stack
|
||||||
|
'OPERATOR UI': '运营界面',
|
||||||
|
'RUNTIME': 'RUNTIME',
|
||||||
|
'SERVICES': '确定性服务',
|
||||||
|
'CONTRACTS': '契约',
|
||||||
|
'SKILLS': 'SKILLS',
|
||||||
|
'DATA': '数据',
|
||||||
|
'LLM BACKENDS': 'LLM 后端',
|
||||||
|
'Case Desk': '运营工单台',
|
||||||
|
'approval inbox · case view · lineage expansion': '审批收件箱 · 工单视图 · 血缘展开',
|
||||||
|
'AI insight cards': 'AI 结论卡片',
|
||||||
|
'read-only projections in existing business pages': '嵌入既有业务页面的只读投影',
|
||||||
|
'TypeScript + Mastra': 'TypeScript + Mastra',
|
||||||
|
'workflows (durable suspend/resume)': '工作流(持久化挂起/恢复)',
|
||||||
|
'agents as controlled steps · tool registry': 'Agent 作为受控步骤 · 工具注册表',
|
||||||
|
'Trigger service': '触发服务',
|
||||||
|
'cron · event bus consumers': '定时 · 事件总线消费者',
|
||||||
|
'router agent for manual requests': '人工请求经路由 Agent',
|
||||||
|
'LLM port': 'LLM 抽象层',
|
||||||
|
'capability interface + model router': '能力接口 + 模型路由器',
|
||||||
|
'LLM-down mode for degraded runs': 'LLM 不可用时的降级运行模式',
|
||||||
|
'Policy engine': '政策包引擎',
|
||||||
|
'versioned, tested policy packs': '版本化、带测试的政策包',
|
||||||
|
'Envelope + authority': '包络 + 授权服务',
|
||||||
|
'envelope match · fresh check · permits': '包络匹配 · 现势复核 · 执行许可',
|
||||||
|
'Ledger + lineage': '账本 + 血缘',
|
||||||
|
'position cascade · snapshots · assembler': '持仓约束级联 · 快照 · 组装器',
|
||||||
|
'Gateways + Case Desk': '网关 + 工单台',
|
||||||
|
'file export · simulation · cases': '文件导出 · 仿真网关 · 工单',
|
||||||
|
'Domain schemas (zod)': '领域 schema(zod)',
|
||||||
|
'single source of truth': '唯一事实来源',
|
||||||
|
'JSON Schema': 'JSON Schema',
|
||||||
|
'exported, committed, versioned': '构建导出、入库、版本化',
|
||||||
|
'Golden fixtures': '黄金样例',
|
||||||
|
'validated by both CIs': '两端 CI 共同校验',
|
||||||
|
'Python services (FastAPI)': 'Python 服务(FastAPI)',
|
||||||
|
'load / PV / price forecasts with quantiles': '负荷 / 光伏 / 电价预测(带分位数区间)',
|
||||||
|
'bid MILP · dispatch MILP · potential · report': '报价 MILP · 调度 MILP · 潜力辨识 · 报告生成',
|
||||||
|
'Generated pydantic models': '生成的 pydantic 模型',
|
||||||
|
'never hand-edited': '禁止手改',
|
||||||
|
'PostgreSQL + pgvector': 'PostgreSQL + pgvector',
|
||||||
|
'relational · knowledge · outbox events': '关系数据 · 知识库 · outbox 事件',
|
||||||
|
'TimescaleDB / IoTDB': 'TimescaleDB / IoTDB',
|
||||||
|
'telemetry curves': '遥测曲线',
|
||||||
|
'Object storage': '对象存储',
|
||||||
|
'snapshots · archives': '快照 · 归档',
|
||||||
|
'Kafka (phase 2)': 'Kafka(二期)',
|
||||||
|
'outbox relay, same interface': 'outbox 中继,消费者接口不变',
|
||||||
|
'Commercial API': '商用 API',
|
||||||
|
'development': '开发期',
|
||||||
|
'Local open model': '本地开源模型',
|
||||||
|
'pre-production': '预生产',
|
||||||
|
'GuangMing Power LLM': '光明电力大模型',
|
||||||
|
'production, on-prem adapter': '生产环境,本地化部署适配器',
|
||||||
|
'Backend swaps are gated by the L1 evaluation set and an L4 shadow comparison, not judgment. About a third of the platform is framework; the differentiating parts are the deterministic services.': '切换 LLM 后端以 L1 评测集与 L4 影子对比为门禁,而非主观判断。框架约解决三分之一的问题,差异化资产是自建的确定性服务。',
|
||||||
|
|
||||||
|
// 06 contracts
|
||||||
|
'Contract pipeline (one source of truth)': '契约管线(唯一事实来源)',
|
||||||
|
'zod schemas': 'zod schemas',
|
||||||
|
'packages/domain · hand-written': 'packages/domain · 唯一手写处',
|
||||||
|
'build export': '构建导出',
|
||||||
|
'contracts/ · committed · versioned': 'contracts/ · 入库 · 版本化',
|
||||||
|
'codegen': '代码生成',
|
||||||
|
'pydantic models': 'pydantic models',
|
||||||
|
'generated · never hand-edited': '生成物 · 禁止手改',
|
||||||
|
'valid + invalid samples per object': '每类对象的正例 + 反例',
|
||||||
|
'TS CI and Python CI both validate every fixture; any disagreement fails the build': 'TS CI 与 Python CI 各自校验全部样例;两端结论不一致即构建失败',
|
||||||
|
'Ports = trust boundaries (deterministic, not exposed to the LLM)': '端口 = 信任边界(确定性,不暴露给 LLM)',
|
||||||
|
'the only way into the safety chain': '进入可信执行链的唯一入口',
|
||||||
|
'rule check and simulation': '规则校核与仿真验证',
|
||||||
|
'envelope match · fresh check · permits · revoke': '包络匹配 · 现势复核 · 签发/吊销许可',
|
||||||
|
'accepts (Proposal, ExecutionPermit) only': '只受理 (Proposal, ExecutionPermit)',
|
||||||
|
'versioned ledger · event-sourced evidence': '带版本账本 · 事件溯源证据',
|
||||||
|
'open · read · apply command · watch': '开单 · 读取 · 执行命令 · 订阅',
|
||||||
|
'Cross-process interfaces and data representation rules': '跨进程接口与数据表示纪律',
|
||||||
|
'TS runtime → Python skills': 'TS Runtime → Python Skills',
|
||||||
|
'HTTP/JSON, schema-validated both ends': 'HTTP/JSON,两端按 schema 校验',
|
||||||
|
'Case Desk / front end → runtime': '工单台 / 前端 → Runtime',
|
||||||
|
'HTTP/JSON approvals and case API': 'HTTP/JSON 审批与工单 API',
|
||||||
|
'anti-corruption adapters, raw + translated logged': '防腐层适配器,原始报文与转换对象双向留痕',
|
||||||
|
'Edge control link': '边缘控制链路',
|
||||||
|
'grid protocol stack, outside the JSON domain': '国网标准协议栈,不属于 JSON 契约域',
|
||||||
|
'Money, energy and prices as fixed-point decimal strings · units in field names (power_mw, price_yuan_per_mwh) · ISO 8601 UTC · intervals as {date, interval_index}': '金额 / 电量 / 电价用定点小数字符串 · 单位编进字段名(power_mw, price_yuan_per_mwh)· ISO 8601 UTC · 时段用 {date, interval_index}',
|
||||||
|
'all IDs strings · enums UPPER_SNAKE · breaking schema changes bump the major version and ship a migration note': '全部 ID 为字符串 · 枚举 UPPER_SNAKE · 破坏性 schema 变更须升主版本并附迁移说明',
|
||||||
|
|
||||||
|
// 07 eval-driven
|
||||||
|
'Four evaluation layers': '四层评测对象',
|
||||||
|
'End-to-end decision quality': '端到端决策质量',
|
||||||
|
'shadow run · historical backtest · counterfactual attribution': '影子运行 · 历史回测 · 反事实归因',
|
||||||
|
'Safety chain correctness': '可信执行链正确性',
|
||||||
|
'policy pack tests · invariant tests I1–I8 · red-team cases': '政策包测试 · 不变式测试 I1–I8 · 红队用例',
|
||||||
|
'Professional-model skills': '专业模型 Skill',
|
||||||
|
'MAPE · interval coverage · solver quality vs. bounds': 'MAPE · 区间覆盖率 · 求解质量对比上下界',
|
||||||
|
'LLM tasks': 'LLM 任务',
|
||||||
|
'routing accuracy · schema compliance · numeric consistency': '路由准确率 · schema 合规率 · 数字一致性',
|
||||||
|
'A problem at L4 is localised to the layer that caused it.': 'L4 出问题时可定位到引起它的那一层。',
|
||||||
|
'Change gates: what must pass before a change ships': '变更门禁:什么变更必须通过什么评测',
|
||||||
|
'Prompt / agent instructions': '提示词 / Agent 指令',
|
||||||
|
'L1 task set + L4 fixed-day backtest, no regression': 'L1 相关任务集 + L4 固定历史日回测无回退',
|
||||||
|
'LLM backend switch': 'LLM 后端切换',
|
||||||
|
'full L1 set + L4 shadow comparison vs. baseline': 'L1 全集 + L4 影子对比达到基线约定比例',
|
||||||
|
'Skill model upgrade': 'Skill 模型升版',
|
||||||
|
'all L2 metrics for that skill + downstream L4 backtest': '该 Skill 的 L2 全指标 + 下游 L4 回测',
|
||||||
|
'Policy pack upgrade': '政策包升版',
|
||||||
|
'L3 pack tests green + impact analysis on pending proposals': 'L3 政策包测试全绿 + 存量 Proposal 影响分析',
|
||||||
|
'Contract schema change': '契约 schema 变更',
|
||||||
|
'golden fixtures on both sides + compatibility check': '双端黄金样例 + 兼容性检查',
|
||||||
|
'Envelope widening': '包络放宽',
|
||||||
|
'L4 shadow / online evidence only — no data, no widening': '仅凭 L4 影子 / 在线数据审批 —— 无数据不放宽',
|
||||||
|
'The audit trail is the evaluation dataset': '审计留痕即评测数据集',
|
||||||
|
'Production run': '生产运行',
|
||||||
|
'event log + immutable snapshots': '事件日志 + 不可变快照',
|
||||||
|
'Replay datasets': '历史重放集',
|
||||||
|
'representative days, frozen': '固化的代表日',
|
||||||
|
'Eval run (archived)': '评测运行(留档)',
|
||||||
|
'committed baseline, CI --check': '已提交基线,CI --check',
|
||||||
|
'ReviewFinding': 'ReviewFinding',
|
||||||
|
'D+1 attribution': 'D+1 偏差归因',
|
||||||
|
'New eval cases': '新评测用例',
|
||||||
|
'every finding → candidate case': '每条复盘结论 → 候选用例',
|
||||||
|
}
|
||||||
BIN
docs/external/img/01-system-context.png
vendored
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 191 KiB |
BIN
docs/external/img/02-agent-runtime.png
vendored
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
BIN
docs/external/img/03-context-memory.png
vendored
|
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 217 KiB |
BIN
docs/external/img/04-safety-chain.png
vendored
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
BIN
docs/external/img/05-tech-stack.png
vendored
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 238 KiB |
BIN
docs/external/img/06-contracts.png
vendored
|
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 227 KiB |
BIN
docs/external/img/07-eval-driven.png
vendored
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 208 KiB |
BIN
docs/external/img/zh/01-system-context.png
vendored
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
docs/external/img/zh/02-agent-runtime.png
vendored
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
docs/external/img/zh/03-context-memory.png
vendored
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
docs/external/img/zh/04-safety-chain.png
vendored
Normal file
|
After Width: | Height: | Size: 175 KiB |
BIN
docs/external/img/zh/05-tech-stack.png
vendored
Normal file
|
After Width: | Height: | Size: 287 KiB |
BIN
docs/external/img/zh/06-contracts.png
vendored
Normal file
|
After Width: | Height: | Size: 260 KiB |
BIN
docs/external/img/zh/07-eval-driven.png
vendored
Normal file
|
After Width: | Height: | Size: 221 KiB |