1872 字
9 分钟
- 次浏览
聊天里跑仿真:把请求收敛为本地任务包
读前导览

仿真请求变成任务包后,再交给固定 runner。跑完只列成果,确认后再回传,避免一句话变成本机命令。

正文
1872 字
阅读
9 分钟
结构
8 节
来源线索

windows-bot-memory/simulation-bridge

windows-bot-memory:simulation-bridge windows-bot-memory:task-agent windows-bot-memory:lab-bridge

实验课最容易出现一种“看起来很顺手”的需求:把电路文件、Verilog 源码或题目截图发给本地助手,然后让它直接跑仿真、画波形、把结果回传。

这个需求本身合理。问题在于中间少了一层:自然语言不该直接变成命令。

我在本地助手里做仿真桥接时,最后把链路拆成了几个硬步骤:聊天请求先变成任务包,任务包只能交给固定 runner,runner 写出结构化成果清单,成果回传再走独立确认。这样系统响应慢一点,但权限和责任清楚很多。

先落成任务包#

使用任务包,主要是为了把这次执行计划固定下来。

一条“帮我跑这个滤波器的 AC 和瞬态响应”的请求,不能在确认后重新解释成另一条命令。它应该先被转成一个结构化 spec,里面只保留这些内容:

{
"task_type": "spice_simulation",
"engine": "hspice",
"project": "analog",
"input_files": ["received_files/example.cir"],
"analyses": ["ac", "tran"],
"outputs": ["run_summary", "measurements", "plot_png"],
"requires_confirmation": true
}

这里最麻烦的通常是那些被刻意删掉的入口:没有 command、没有 shell、没有工作目录、没有任意参数数组,也不能让模型指定可执行程序。

任务包只描述“我要做哪类仿真、输入来自哪里、希望产出什么”。至于怎么调用工具,由系统内置 runner 决定。

固定 runner 比任意命令可靠#

Vivado、HSPICE、LTspice 都是复杂工具。最省事的接法,是让模型拼一条命令行。不过这会很快失控:路径、参数、环境变量、输出文件、临时目录、超时、失败归因都会散在自然语言和命令字符串里。

固定 runner 的做法更笨,也更适合长期维护。

Vivado runner 只接受源码或安全解包后的源码包,先扫描模块,再决定是否缺 top 或 testbench。有明确入口时,才按固定阶段完成编译、elaboration 和仿真,并导出波形成果。

HSPICE runner 只处理受控网表和分析类型,负责收集测量表、日志、波形图和失败摘要。参数扫描、.alter、测量失败这些细节,也由 runner 归类。

LTspice runner 只处理允许的电路文件,拒绝混合在一个网表里的不合理分析组合,失败时从日志里抽摘要,而不是把整段原始输出扔回聊天。

这样做的好处是,模型负责理解意图,runner 按固定流程执行。两者之间只有任务包,不共享自由命令入口。

输入和输出要分区#

实验自动化里,文件目录比想象中重要。

输入只能来自固定接收区或受控本地任务区。任务执行时,把需要的输入复制进当前任务包的 inputs/,后续 runner 只看这份副本。这样即使原始文件后来被替换,任务包仍然能解释自己当时跑了什么。

输出也不能散落。每个任务包至少应该有:

  • task-request.json:确认时冻结的 spec。
  • run-summary.md:给人看的摘要。
  • runner-result.json:给系统看的执行结果。
  • status-events.jsonl:阶段事件。
  • artifacts.json:可回传成果清单。
  • inputs/:本次执行使用的输入副本。

这套结构看起来啰嗦,但它能解决一个很实际的问题:仿真失败时,用户需要知道失败在哪个阶段;仿真成功时,系统需要知道哪些成果适合默认回传,哪些只留在本地等待点名。

成果回传是第二个动作#

跑完仿真不等于应该立刻把所有文件发出去。

波形 PNG、摘要 Markdown、测量表通常可以默认候选;大型 raw、WDB、VCD、完整日志、源码包就要更谨慎。它们可能很大,也可能包含过多环境信息。

所以任务完成后,更倾向于生成一张成果清单:每个文件有类型、大小、默认是否回传、跳过原因。后续要上传或发送时,再单独确认一次。

这条限制很有用。确认“在本机跑仿真”和确认“把成果发到外部会话”,不是同一个授权。

失败要给阶段#

仿真系统最糟糕的输出,是只丢回来一句“失败”。

对用户来说,缺 testbench、编译失败、license 不可用、模型库缺失、测量表达式失败、波形解析失败,是完全不同的问题。一个好的 runner 至少要把失败落到阶段上:

packet_created
runner_started
runner_finished
artifacts_ready

如果卡在编译,就别假装是波形问题。如果测量失败但仿真跑完了,也别把整次任务说成“不可用”。阶段事件和摘要文件能让用户快速判断下一步该补题干、补模型、补 testbench,还是只需要调整输出要求。

图片题先做分析,别假装已完成#

课程题里还有一种麻烦输入:截图、扫描件、DOCX 里的嵌入图片。

这种题很适合先生成 problem-analysis.md,而不是直接跑仿真。分析文件可以记录题目识别结果、已知参数、缺失信息、公式路线、手算计划和仿真计划。

如果参数齐全,可以生成一个初始网表或 testbench 草稿,并标成可运行候选。如果题干缺模型、时钟、器件参数或完整端口定义,就应该明确返回 needs_info。这比“猜一个电路然后跑出一张图”可靠得多。

图片理解不是仿真完成。它只是把非结构化题目推进到结构化任务包的一步。

本地桥接也要保持轻量#

这套设计不需要在服务器上跑重任务。服务器只适合做提醒、状态和轻量页面;依赖 Windows 工具、许可证、GUI 或大成果处理的仿真,留在本地。

本地桥接层也不该变成一个通用远程执行服务。它可以提供健康检查、只读状态、创建计划、归档输入、生成确认请求、调用固定 runner。它不需要提供“执行任意命令”的接口。

一旦系统有了固定 job type 和确认 TTL,就能把自然语言入口限制在几个可审计动作里:计划、确认、执行、列成果、回传。

现在的判断#

聊天里跑仿真,最后要防住两件事:工具权限过大,自然语言解释空间过大。

一个稳一点的实验自动化链路,应该满足这些条件:

  • 请求先冻结成任务包。
  • 输入只来自固定接收区或受控任务区。
  • spec 不能包含自由命令字段。
  • 执行只能走 Vivado、HSPICE、LTspice 这类固定 runner。
  • 每个阶段写事件,失败要归因。
  • 成果清单区分默认回传和本地保留。
  • 外部回传要和本地执行分开确认。
  • 图片题先分析,信息不足就返回缺口。

这样做之后,助手依然能节省大量重复劳动:建任务、跑仿真、收波形、汇总测量、整理报告片段。

但它不会因为一句“帮我跑一下”就获得整台机器的自由命令入口。对实验自动化来说,这条限制比多支持一个仿真参数更重要。

聊天里跑仿真:把请求收敛为本地任务包
https://blog.sunmmyapi.xyz/posts/simulation-task-packet-before-runner/
作者
Sun
发布于
2026-05-29
许可协议
CC BY-NC-SA 4.0

继续读

相关内容