Skip to content

场景参考 ​

一个场景就是一份 YAML 或 JSON 文档。校验它的是 src/core/schema.ts 里的 ScenarioSchema,本页的每个类型与默认值都读自这份 schema:场景文件、POST /api/runs 的请求体、MCP 的 run_scenario 工具,走的都是同一套定义。解析器会丢掉不认识的键,所以键名拼错不会让校验失败;运行目录里的 scenario.json 存的是补齐默认值、解析完参数之后的有效场景。

顶层字段 ​

字段typedefault说明
scenarioIdnon-empty stringrequired给运行命名。运行 id 是 <scenarioId>:<replicationId>。
seedintegerrequired本次运行全部随机流的根。
replicationIdinteger, at least 00由审计 harness 为每次复制设置。
seedPathinteger[][]根 seed 之下的派生路径;harness 会把复制序号追加到末尾。
paramsobject{}自由形式的值。插件选项用 $param 引用它们,审计的轴以 params.<name> 为 target。
populationobjectrequired规模、人格字段与抽样。见人口。
modulesPluginSpec[][]世界模块,在所有执行体行动完之后按顺序步进。
executorsPluginSpec[][]执行体;每个都在 options.provider 里指明自己靠哪个提供者做决策。
providersmap of name to PluginSpec{}决策提供者,键名就是执行体与组合提供者引用它时用的名字。
policyPluginSpec{ kind: allAgents }激活策略:每个 tick 由哪些 agent 行动、以什么模式行动。
instrumentsInstrumentSpec[][]指标与问卷。见仪器。
stepsStep[][]运行日程。见步骤。
llmobjectevery field defaulted网关设置。见 LLM。
promptobjectevery field defaulted人格、指令与记忆写给模型时的形态。见提示词。
pluginsstring[]omitted导出 register(registry) 的模块,路径相对场景文件解析。
hypothesisobjectomitted干预与审计用的臂和结果。见假设。

插件规格 ​

modules、executors、providers、policy 与 instruments 用的是同一种引用形式。

字段typedefault说明
kindnon-empty stringrequired插件注册表里已注册的 kind。见内置 kind。
namenon-empty stringthe kind实例名。指标以它为名上报,模块与提供者按它寻址。
optionsobject{}由插件自己的 zod schema 校验;选项非法时装配失败,并报出其路径。

执行体、策略与提供者都不接受多余字段。focal 执行体的选项是 provider(必填)、components(组件列表)、entity(默认 agent)、actions(已注册动作的一个子集)与 where(一张谓词表,把执行体限制在匹配的 agent 上,例如 where: { persona.role: player })。cohort 执行体接受 provider、features、transition、virtualActions、fallbackAction、neighborMean、where 与 recordFeatures;examples/echo_chamber/cohort.yaml 把它们全都用上了。

参数引用 ​

插件选项要取值的任何地方,以及 population.n,写成 { $param: <name> } 的对象都会在插件构造之前替换成 params.<name>。可选的 map 把参数的值当作字符串键,翻译成选项的值,于是一个枚举或数值参数可以驱动另一种类型的选项:

yaml
params:
    framing: canonical
executors:
    - kind: focal
      options:
          components:
              - kind: instructions
                options:
                    text:
                        $param: framing
                        map:
                            canonical: You are playing a repeated prisoner's dilemma.
                            moralized: Cooperating is the honest choice.

参数不存在,或 map 里缺了对应的值,都会在该选项的路径上校验失败。population.n 在文档解析时就解析完,必须得到一个正整数;之后再覆盖 params.n 也不会重新推导它。审计的轴覆盖的是 params.framing 这类点分路径,所以一条轴就能触及所有引用该参数的选项。

人口 ​

字段typedefault说明
npositive integer or { $param }required人口规模。
fieldsPersonaField[][]人格列,落成 persona.<name>。
source{ kind: synthetic }, { kind: csv, path } or { kind: json, path }{ kind: synthetic }行数据从哪里来。
provenancedemographic, survey, interview or syntheticsynthetic记录下来的人口来源。
stratifymap of field to map of value to weightomitted每个取值的目标比例,例如 role: { player: 1, opponent: 1 }。

一个人格字段:

字段typedefault说明
namenon-empty stringrequired
dtypef64, i32, bool, str or strlistrequired列类型。
privatebooleanomitted私有字段永远不进提示词,也会从 API 返回的 agent 行里剔除。
sampling见下required值怎么抽。

抽样是三者之一:{ kind: value, value }(常量)、{ kind: choice, choices, weights? }(至少一个候选,权重可选且不能为负)、{ kind: range, min, max }(数值区间)。

步骤 ​

步骤按顺序执行。没有步骤的场景一个 tick 都不跑。

步骤fields效果
{ kind: run, ticks }ticks: positive integer把模拟推进这么多个 tick。
{ kind: intervene, arm, instruction? }arm: the name of an arm in hypothesis; instruction: string应用该臂的覆盖项,并通过 instructions 组件把它的指令交给选中的 agent。
{ kind: questionnaire, name, targets? }name: an instrument of kind questionnaire; targets: a selector访谈选中的 agent;回答成为 measurement 事件,绝不触碰世界状态。
{ kind: checkpoint }写出 checkpoints/<tick>/:世界快照、时钟、执行体与提供者状态。

simulacra resume 从检查点目录续跑,会跳过排在检查点之后的干预步骤与问卷步骤;要跑这些步骤,就从头跑一次。

选择器 ​

问卷步骤里的 targets,以及假设某个臂里的 selection,都是选择器:

字段typedefault说明
wheremap of column to predicaterequired所有谓词都要成立。
fractionnumber in [0, 1]omitted在匹配到的 agent 里随机取的比例。
npositive integeromitted在匹配到的 agent 里取固定的个数。

谓词写成 { in: [values] }、{ gt: number }、{ lt: number },或者直接给一个字面值表示相等。操作符对象是严格的:{ gt: 1, typo: 2 } 会被拒绝,而不是被当成对整个对象的相等判断。

LLM ​

llm 块配置的是所有依赖 LLM 的插件共用的那一个网关。整块不写、或其中某个字段不写,得到的都是 DeepSeek 预设。

字段typedefault说明
baseUrlnon-empty stringhttps://api.deepseek.com/v1任何 OpenAI 兼容端点。
modelnon-empty stringdeepseek-v4-flash也是审计轴 model_substrate 与计划里 models 列表作用的地方。
apiKeyEnvnon-empty stringSIMULACRA_LLM_API_KEY存放密钥的环境变量名;密钥本身永远不写进 YAML。
modelive, record or replayliverecord 把每条响应写到 recordDir 下,replay 从那里离线作答。
recordDirnon-empty stringomitted录制目录,相对场景文件。
concurrency.initialpositive integer4网关 AIMD 控制器的初始在途上限。
concurrency.maxpositive integer16同一个控制器的天花板。
structuredauto, json_schema or promptauto结构化输出模式;auto 会探测端点是否支持 json_schema。
budget.maxCallsinteger, at least 01000每次运行的调用次数上限,超出后网关拒绝继续请求。
budget.maxCompletionTokenspositive integer512单次调用的补全上限;LLM 提供者不能要得更多。
timeoutMspositive integer60000单次请求的超时。
sendSeedbooleantrue请求里是否带 seed 字段;mlx-lm 预设会关掉它。
extraobjectomitted请求体里额外的字段,例如给 DeepSeek 的 { thinking: { type: disabled } }。网关自己占用的键不能被覆盖。

提示词 ​

prompt 块决定同一份人格、指令与记忆写给模型时长什么样。每个字段都是扰动轴目录里某条表示轴的默认 target。

字段valuesdefault
personaFormatplain, bullets, tableplain
instructionOrderfirst, lastfirst
rolePlacementsystem, usersystem
namingid, name, anonymousid
memoryRepresentationtranscript, json, bulletstranscript
contextWindowpositive integer4000

仪器 ​

一条 instruments 条目是一份插件规格,外加 every:一个正整数,给出测量的 tick 间隔(默认每个 tick 都测)。注册为指标的 kind 从世界状态与事件日志算出一个数或一列数,并写一条 measurement 事件;注册为仪器的 kind 是问卷,questionnaire 步骤按名字引用它。questionnaire 这个 kind 接受 questions(至少一个 { id, prompt, responseType, choices? },其中 responseType 取 text、integer、float 或 choice,取 choice 时必须给出 choices)与 entersMemory(默认 true)。

假设 ​

字段type说明
idnon-empty string
claimstring用文字写出的主张。
claimTypeexploratory, mechanism or policypolicy 类主张想拿 strong 等级,三个层级上都得有轴。
armsArm[]{ name, role: treatment or control, overrides (default {}), selection? }。
outcomesOutcome[]{ name, metric, direction: increase, decrease or any (default any), targetDistribution?: number[] }。

干预步骤点名一个臂:它的 overrides 应用到场景上,它的 selection 挑出 agent。在审计计划里,outcomes 给每个指标一个期望方向,配上 targetDistribution 就是分布检验的目标。

内置 kind ​

每个 kind 自己校验自己的选项;schema 就在标出的文件里。

槽位kind
modulessocialGraph(有向边表,follow 与 unfollow,在 tick 0 之前生成一次;src/modules/socialGraph.ts)、feed(帖子表,post、repost、reply、like 与 silent,每个用户一份排序过的 feed;推荐器有 random、recency、followingFirst、homophily;src/modules/feed.ts)、calendar(src/modules/calendar.ts)
executorsfocal(src/agents/focal.ts)、cohort(src/agents/cohort.ts)
components,在 focal 里persona、instructions、recentMemory、summaryMemory、feedObservation、neighborhoodObservation(src/agents/components/)
transitions,在 cohort 里opinionDynamics(src/agents/transitions/opinionDynamics.ts)
providersllm、mock、rule、cohortRule、archetype、surrogate、cache、topo、aps(src/providers/);rule 需要在代码里注册一个规则函数,所以插件通常改为注册自己的 kind
policiesallAgents、bernoulli(p)、profileHourly(column、ticksPerHour)、maskTimer(maskColumn、timerColumn)、explicit(schedule);全都接受 entity 与 mode(src/policies/index.ts)
metrics,作为仪器使用columnMean、cooperationRate、averagePayoff、stanceAssortativity、sameGroupRatio、actionShare、tvdToTarget(src/metrics/index.ts)
instrumentsquestionnaire(src/instruments/questionnaire.ts)
adaptersscript、oasis(src/adapters/)

examples/ 里自带的场景用掉了其中大部分;仓库里最短的完整场景是 examples/programmatic/02-custom-plugin.ts 里的那段 YAML 字符串,插件页面有全文。