版本号:v0.1.0 最后更新:2026-04-04
说明:本版为按规范整理的历史文档,正文暂保留原英文内容。
This document defines the core shared data model for the multimodal analysis framework.
These data structures are the foundation for:
This document is intended to be the first implementation-facing specification after the architecture documents.
It complements:
The core data model should be:
The first implementation should prefer simple, explicit schemas over clever abstractions.
The first version of the system should standardize five primary entities:
InputSourceObservationAlgorithmModuleEvidenceExperimentThese entities should be sufficient to support:
InputSource describes where data comes from and what it is capable of producing.
Examples:
type InputSource = {
id: string
kind: "audio" | "rf" | "video" | "optical" | "bus" | "file" | "log"
name: string
capabilities: string[]
deviceInfo?: Record<string, unknown>
supportedFormats: DataFormat[]
location?: SourceLocation
status: "available" | "busy" | "offline" | "error"
createdAt: string
updatedAt: string
}
InputSource is not the captured data itself.Observation is a concrete captured sample or replayable unit of data plus its context.
Examples:
type Observation = {
id: string
sourceId: string
modality: "audio" | "rf" | "video" | "optical" | "bus" | "log"
format: DataFormat
payloadRef: string
byteSize?: number
timeRange: {
start: string
end: string
}
captureMetadata: Record<string, unknown>
tags: string[]
createdAt: string
}
For the audio-first product, captureMetadata may include:
payloadRef should point to a stable storage reference rather than embedding large binary data directly.Observation should be replayable.DataFormat describes the structural format flowing between modules.
type DataFormat = {
family: string
encoding: string
shape?: Record<string, unknown>
}
{ family: "audio", encoding: "wav_pcm16" }{ family: "audio", encoding: "spectrogram_f32" }{ family: "rf", encoding: "complex_iq_f32" }{ family: "signal", encoding: "soft_bits" }{ family: "packet", encoding: "pcap_frame" }AlgorithmModule defines a registered processing block that can be used in a pipeline.
Examples:
type AlgorithmModule = {
id: string
name: string
version: string
modality: string[]
stage: string
inputFormat: DataFormat
outputFormat: DataFormat
params: Record<string, ParamSpec>
metrics: string[]
executionModel: "in_process" | "out_of_process" | "sandboxed"
trustLevel: "core" | "trusted" | "partner" | "experimental" | "untrusted"
realtimeSafe: boolean
source: ModuleSource
dependencies?: string[]
createdAt: string
updatedAt: string
}
type ParamSpec = {
type: "int" | "float" | "bool" | "string" | "enum"
required?: boolean
defaultValue?: unknown
range?: [number, number]
choices?: string[]
description?: string
}
type ModuleSource = {
provider: string
packageName?: string
license?: string
originType: "builtin" | "pack" | "third_party" | "ai_generated"
}
PipelineNode captures one configured module instance inside an experiment pipeline.
type PipelineNode = {
moduleId: string
params: Record<string, unknown>
enabled: boolean
}
AlgorithmModule is a registry definition.PipelineNode is a concrete use of that module with specific parameters.Evidence is the structured result that AI and downstream logic reason over.
It should represent facts, measurements, ranked hypotheses, or anomalies produced by algorithms.
type Evidence = {
id: string
observationId: string
experimentId: string
producerModuleId?: string
category: "signal" | "feature" | "frame" | "protocol" | "semantic" | "anomaly"
values: Record<string, unknown>
confidence: number
scoreContribution?: number
traceRefs: string[]
createdAt: string
}
Examples for audio-first execution:
Evidence should be human-reviewable and machine-consumable.ScoreCard summarizes how well an experiment performed.
type ScoreCard = {
total: number
components: Record<string, number>
penalties?: Record<string, number>
notes?: string[]
}
Experiment records one pipeline execution attempt over an observation.
This is the main unit of search, replay, validation, and AI orchestration.
type Experiment = {
id: string
observationId: string
parentId?: string
pipeline: PipelineNode[]
status: "pending" | "running" | "done" | "failed" | "cancelled"
outputs: ExperimentOutput[]
evidenceIds: string[]
score: ScoreCard
failureReasons: string[]
runtimeStats?: RuntimeStats
createdAt: string
startedAt?: string
finishedAt?: string
}
type ExperimentOutput = {
stage: string
format: DataFormat
payloadRef: string
metadata?: Record<string, unknown>
}
type RuntimeStats = {
elapsedMs: number
cpuMs?: number
peakMemoryMb?: number
}
The first-order relationships are:
InputSource produces many ObservationObservation can have many ExperimentExperiment contains many PipelineNodeExperiment produces many EvidenceAlgorithmModule may be used by many PipelineNodeSimple view:
InputSource
-> Observation
-> Experiment
-> PipelineNode
-> Evidence
The core model should be serializable to JSON and representable in Protobuf later.
Recommended rule:
This avoids locking in transport too early while still keeping future RPC clean.
The first implementation should specialize the generic model only where necessary.
Recommended first concrete instances:
InputSource.kind = "audio"Observation.modality = "audio"DataFormat.family = "audio"AlgorithmModule.stage values such as:
preprocesssegmentfeature_extractdetectclassifyexplainThis keeps the shared model intact while letting audio move quickly.
Do not:
These would make later scaling much harder.
After this model is accepted, the next implementation-facing work should be:
The first implementation should standardize the system around five entities:
InputSourceObservationAlgorithmModuleEvidenceExperimentThese should remain the stable backbone of the platform while modalities, algorithms, and products evolve on top of them.