☰
Aspen EDR 二次开发教程(19):LLM-Agent 与 EDR 数据面协作——工具边界与防幻觉闸门
2026/9/28 3:11:33 网站建设 项目流程

Aspen EDR 二次开发教程(19):LLM-Agent 与 EDR 数据面协作——工具边界与防幻觉闸门

版本声明块

  • 软件:Aspen EDR 家族 + Aspen Plus / Aspen HYSYS(aspenONE V15 为讨论基线)
  • 语言/环境:Python 3.x 64 位;Agent 侧为通用工具调用(本系列不绑定任何具体框架)
  • 本文目标:给出一条"Agent 用得上、又不会越界"的协作路线,并把防幻觉做成机制而非口号
  • 事实来源纪律:官方未公开任何面向 EDR 的 LLM/MCP 支持;相关实践属社区做法(D 级),本系列一律标注等级,不写成官方能力

一句话结论:让大模型 Agent 参与 EDR 工作的唯一安全范式是"Agent 只做只读查询与建议,写操作与设计判断必须过人工闸门"——因为 EDR 侧 ProgID 未公开(铁律 EDR-2)、Operation类告警"could affect the performance and safety of the unit"(铁律 EDR-7)、以及Accept Design是"把 EDR 模型关联回流程换热器块"这一实质性动作;配套机制有三件:工具白名单(只暴露读与检索)、知识底座(变量清单 / 告警经验库 / 交付记录 / 环境档案)、以及输出守卫(任何未登记的 EDR API 名一律拒绝并提示"以官方文档为准")。

〇、本篇要解决的认知问题

  1. 大模型 Agent 在 EDR 这件事上能帮什么忙?为什么"能帮的忙"比大多数人想象的少,但价值并不低?
  2. 把哪些能力做成工具交给 Agent 是安全的,哪些一旦交出去就会出事?判断标准是什么?
  3. 我手上已经攒了四类资产(变量清单、告警经验库、交付记录、环境档案)——怎么把它们变成 Agent 能用的"知识底盘"?
  4. 最危险的事是 Agent 编造一个不存在的 EDR API 名。我能不能用机制(而不是靠提醒)把它挡住?
  5. MCP 这类接口在化工软件自动化里的现状如何?哪些是官方能力,哪些是社区实践?我该以什么证据等级看待它们?

一、机制解析

19.1 Agent 能帮什么、不能帮什么

先给一个不含幻想的清单。判断依据只有一条:这个动作出错后,后果是否可逆、是否能被人发现。

能做(安全)为什么安全
查询数据面:“E-101 上个月的比值趋势如何”只读
检索经验库:“Fluid Elastic Instability 历史上怎么处理的”只读,且带source
解释结果:“为什么这台被判usable=False”只读 + 基于已落盘的判定原因
生成报告草稿(基于结构化结果)产物可复核,不触发计算
辅助定位:“这个告警属于官方三类的哪一类”只读 + 有官方依据
不能做(危险)为什么危险
直接改流程/EDR 参数并提交计算会真实启动模拟器、消耗许可、产生工程后果
代做设计判断(选哪个几何、是否接受)这是工程责任,不是文本生成
越过Operation告警判定"可以用"安全性相关,铁律 EDR-7
自行编造/推断 EDR API 名或 ProgID铁律 EDR-2;会静默连错对象
删除或改写结果与日志破坏审计链

这张表的结论:Agent 在本领域的最佳位置是**“数据面的自然语言检索入口 + 报告草稿生成器”**,而不是"自动化操作员"。

19.2 工具白名单:把"安全边界"写成代码

安全的边界不能只写在文档里,必须写成白名单——只有清单里的工具能被调用,清单外的能力根本不存在。设计原则:

原则说明
默认只读所有工具默认只读;写操作需单独申请并过闸门
无副作用优先工具不应启动模拟器、不占许可(除非明确标注)
输出可审计每个工具返回结构化的、带出处的数据,而不是自由文本
失败显式工具失败返回明确错误,不返回"看起来合理的默认值"

特别地,涉及"启动模拟器"的工具必须被单独隔离,因为它是有成本、有副作用的(第 07/18 篇)。把这类工具与只读检索工具混在一张清单里,等于给 Agent 一把随时能消耗许可的钥匙。

19.3 知识底盘:把四类资产变成可检索知识

第 14 篇的"可审计三件套"加上第 16 篇的经验库,合起来正好是 Agent 的知识底盘:

资产回答什么对 Agent 的价值
变量清单(edr_var_names.json)哪个变量名是真的直接压住"编造变量名"这个风险
告警经验库(warning_experience.jsonl)某类告警历史上怎么处理给出带出处的处置建议
交付记录(edr_results_deliverable.csv)哪些结果可交付、为什么让 Agent 的解释有据可依
环境档案(edr_env_report.txt)在什么环境下产生避免跨环境比较的误判

这四类资产有一个共同特征:它们都是"本机事实 + 出处"。这正是 Agent 最需要的东西——因为 Agent 最大的风险是"生成一个语义上合理但事实上不存在的名字",而知识底盘里的清单就是事实边界。

(最佳实践)让检索工具返回"命中/未命中"两种明确结果,而不是"最相近的若干条"。前者能让 Agent(和用户)直接判断"这个变量名/告警类型到底有没有登记",从机制上抑制幻觉。

19.4 输出守卫:用机制挡住"编造的 EDR API 名"

这是本篇最重要的一节。前面所有篇章都在强调"不编造 EDR ProgID 与成员名",本篇要把它变成可执行的守卫:

守卫层做法
白名单维护一份"已核验/已取证"的实体名清单(流程侧 ProgID + 本机取证的 EDR 相关名 + 已登记变量名)
截获对 Agent 输出中所有形如App.Object的字符串做扫描
比对不在白名单内的,一律标记为"未登记"
拒绝未登记的名字不得进入可执行脚本;提示"以官方文档或本机取证为准"

注意白名单要区分来源:流程侧 ProgID(Apwn.Document/HYSYS.Application)是官方已核验;EDR 相关名是本机取证(铁律 EDR-2)。两者的可信度不同,白名单里也要分级——这直接对应第 01 篇的证据分级纪律。

(经验法则)"未登记即拒绝"比"未登记即警告"更有效。警告会被忽略,拒绝会迫使流程走回取证。

19.5 MCP 一类接口:社区实践与证据等级

关于"用 MCP 让大模型直接操作化工模拟软件",需要给一个诚实的现状描述:

事实等级
官方未公开任何面向 Aspen Plus / Aspen HYSYS / Aspen EDR 的 LLM 或 MCP 支持事实(未检索到即"未发现",不等于"不存在")
社区存在通过 COM 让大模型操作流程模拟软件的项目(通常要求特定版本与 Python 版本)D 级:社区做法,非官方支持
这类项目底层仍是 pywin32 调 COM,能力边界受本文前述所有约束可推断但不等于官方背书

表述纪律:写方案时必须写成"社区已有此类实践,非官方支持,其能力边界与本文所述 COM 约束一致",不得写成"官方支持用大模型操作 EDR"。这与第 01 篇"官方无 Python 包"的处理方式一致。

19.6 人工闸门:哪几个动作必须留人

按"后果严重程度 + 可逆性"排出必须保留人工闸门的动作:

动作为什么必须留人
Accept Design官方定义是"把 EDR 模型关联回流程换热器块"——这是实质性状态变更(第 03 篇)
处置Operation类告警官方:“could affect the performance and safety of the unit”(铁律 EDR-7)
设定/切换默认 EDR 版本影响所有后续自动化的版本锚点(铁律 EDR-3)
定义目标函数与权重决定"什么是最优",是工程价值判断(第 15 篇)
阈值设定(如结垢报警)影响现场行动(第 17 篇)

共同点是:这些动作的"正确答案"依赖工程判断,而不依赖文本生成能力。Agent 可以做的是"把选项、依据、历史案例摆出来",不是"替你做选择"。

二、完整代码与逐行剖析

2.1 代码一:工具白名单定义(只读优先)

# agent_tools.py —— Agent 工具白名单:默认只读,写操作单独隔离importjson# 标准库importos# 标准库# 工具注册表:read_only=True 的工具不含副作用;side_effect=True 的必须单独审批TOOLS={"search_variables":{"read_only":True,"side_effect":False,"desc":"在变量清单中检索变量名(命中/未命中)",},"search_experience":{"read_only":True,"side_effect":False,"desc":"在告警经验库中检索某类告警的历史处置(含出处)",},"query_delivery_records":{"read_only":True,"side_effect":False,"desc":"查询交付记录(含 usable 与三类告警计数)",},"explain_unusable":{"read_only":True,"side_effect":False,"desc":"解释某条记录为何 usable=False",},"start_simulation":{# 危险:会启动模拟器并占许可"read_only":False,"side_effect":True,"desc":"启动流程/EDR 计算(会占用许可,须人工审批与配额)",},}defallowed_tools(allow_side_effect=False):"""返回当前允许的工具清单;默认排除有副作用的工具"""return{k:vfork,vinTOOLS.items()ifv["read_only"]or(allow_side_effectandnotv["read_only"])}defmain():print("="*78)print("[默认允许](无副作用)")fork,vinallowed_tools(False).items():print(f"{k:22s}{v['desc']}")print("-"*78)print("[需显式审批](有副作用,会消耗许可)")fork,vinTOOLS.items():ifv["side_effect"]:print(f"{k:22s}{v['desc']}")print("-"*78)print("[纪律] 有副作用的工具不得与只读工具混在一张清单里下发;")print(" 它是'随时能消耗许可的钥匙',必须单独走审批与配额")print("="*78)withopen("agent_tools.json","w",encoding="utf-8")asfh:json.dump(TOOLS,fh,ensure_ascii=False,indent=2)print("[落盘] agent_tools.json")if__name__=="__main__":main()

逐行剖析:

  1. TOOLS用read_only与side_effect两个字段显式标注每个工具的性质。这不是装饰:它让"哪些能默认暴露"变成可计算的问题。
  2. allowed_tools(allow_side_effect=False)默认只返回只读工具。默认安全是这个设计的第一原则。
  3. start_simulation被单独隔离并注明"会占用许可,须人工审批与配额"。这与第 18 篇"许可要可观测、并发要有人管"一脉相承。
  4. 结尾纪律强调"有副作用的工具不得与只读工具混在一张清单里下发"——这是防事故的关键一条。

2.2 代码二:知识检索工具(返回命中/未命中)

# agent_knowledge.py —— 三个只读检索工具:变量名、经验库、交付记录importjson# 标准库importos# 标准库defsearch_variables(name,inventory_path="edr_var_names.json"):"""在变量清单中检索:返回命中/未命中,不做'最相近'猜测"""ifnotos.path.isfile(inventory_path):return{"found":False,"reason":"变量清单文件不存在(请先按第 04 篇回收)"}withopen(inventory_path,"r",encoding="utf-8")asfh:inv=json.load(fh)names={r.get("var_name")forrininvifisinstance(r,dict)}ifnameinnames:return{"found":True,"var_name":name}# 命中return{"found":False,"reason":f"变量名未登记:{name}(请用本机 Variable List 核实,不得推断)"}defsearch_experience(warning_type,db_path="warning_experience.jsonl"):"""在经验库中检索:返回带 source 的记录"""ifnotos.path.isfile(db_path):return{"found":False,"reason":"经验库不存在(请先按第 16 篇沉淀)"}hits=[]withopen(db_path,"r",encoding="utf-8")asfh:forlineinfh:ifline.strip():rec=json.loads(line)ifwarning_type.lower()inrec.get("warning_type","").lower():hits.append(rec)ifnothits:return{"found":False,"reason":f"经验库中无 '{warning_type}' 的记录;如有处置请按第 16 篇补录"}return{"found":True,"records":hits}# 每条都带 sourcedefmain():print("="*78)print("[示例] 检索一个不存在的变量名:")print(" ",search_variables("<某个未登记的变量名>"))print("[示例] 检索一个不存在的告警类型:")print(" ",search_experience("<未登记的告警类型>"))print("-"*78)print("[设计要点] 命中/未命中二元返回,而非'最相近的若干条'——")print(" 前者能直接压制幻觉,后者会诱导模型把近似当成事实")print("="*78)if__name__=="__main__":main()

逐行剖析:

  1. search_variables只做精确匹配,返回found: True/False。这是对"编造变量名"的正面拦截:未登记就是未登记,不给"近似项"。
  2. 未命中的reason里直接写"请用本机 Variable List 核实,不得推断"——把纪律写进工具返回值,让 Agent 与用户都能看到边界。
  3. search_experience返回的记录每条都带source(第 16 篇的必填字段),因此 Agent 引用时天然带上出处。
  4. 两个found: False分支都给出"下一步该做什么"(回收清单 / 补录经验),把失败变成可行动的提示。
  5. 结尾把设计要点讲清:二元返回 vs 近似返回的差别,是本篇防幻觉的核心机制之一。

2.3 代码三:输出守卫(拒绝未登记的 EDR API 名)

# agent_guard.py —— 扫描 Agent 输出中的 API 形态字符串,比对白名单并拒绝importre# 标准库importjson# 标准库importos# 标准库# 白名单分两级:官方已核验(流程侧)与本机取证(EDR 相关)OFFICIAL_VERIFIED={"Apwn.Document":"官方 KB 000083571(Aspen Plus ActiveX 自动化服务器)","HYSYS.Application":"Aspen HYSYS 自动化(应用级对象)","HYSYS.SimulationCase":"Aspen HYSYS 案例级对象",}LOCAL_ATTESTED_PATH="edr_progid_candidates.json"# 第 06 篇产出的本机取证候选# 形如 App.Object 的字符串API_PATTERN=re.compile(r"\b[A-Za-z][A-Za-z0-9_]{1,40}\.[A-Za-z][A-Za-z0-9_.]{1,40}\b")defload_local_whitelist(path):"""装载本机取证得到的候选(来源:第 06 篇)"""ifnotos.path.isfile(path):returnset()withopen(path,"r",encoding="utf-8")asfh:data=json.load(fh)returnset(data)ifisinstance(data,list)elseset()defguard(text):"""扫描文本,返回 (允许清单, 未登记清单)"""found=set(API_PATTERN.findall(text))local=load_local_whitelist(LOCAL_ATTESTED_PATH)allowed,unregistered=[],[]fornameinsorted(found):ifnameinOFFICIAL_VERIFIED:allowed.append({"name":name,"level":"官方已核验","source":OFFICIAL_VERIFIED[name]})elifnameinlocal:allowed.append({"name":name,"level":"本机取证","source":"本机模板 VBA / 注册表枚举"})else:unregistered.append(name)# 未登记:一律拒绝returnallowed,unregistereddefmain():# 模拟一段 Agent 输出(其中含一个编造的 EDR 名)agent_text=("这段脚本会连接 Apwn.Document 并调度计算,""然后用 AspenEDR.Application 直接读取换热器结果。")allowed,unreg=guard(agent_text)print("="*78)print("[允许] 已登记的实体名:")forainallowed:print(f"{a['name']}[{a['level']}] 出处:{a['source']}")print("-"*78)ifunreg:print("[拒绝] 未登记的实体名(不得进入可执行脚本):")forninunreg:print(f"{n}-> 未登记:以官方文档为准,或按第 06 篇在本机取证后补登白名单")else:print("[拒绝] 未发现未登记实体名")print("-"*78)print("[原因] EDR 侧 ProgID 官方未公开;任何未取证的名字都无法保证在本机存在(铁律 EDR-2)")print("="*78)withopen("agent_guard.json","w",encoding="utf-8")asfh:json.dump({"allowed":allowed,"unregistered":unreg},fh,ensure_ascii=False,indent=2)print("[落盘] agent_guard.json")if__name__=="__main__":main()

逐行剖析:

  1. 白名单分两级:OFFICIAL_VERIFIED(官方已核验的流程侧 ProgID,附官方出处)与本机取证(从第 06 篇的候选文件装载)。分级是因为可信度不同——这与第 01 篇的证据分级完全一致。
  2. API_PATTERN用宽松正则捕捉形如App.Object的字符串,宁可多捕也不漏捕(多捕只会多一次人工核对,漏捕会导致幻觉漏网)。
  3. guard对每个命中名逐一分类:官方已核验 / 本机取证 / 未登记,未登记进拒绝清单并给出"补登白名单"的动作。
  4. 演示文本里故意放了AspenEDR.Application——一个"看起来极其合理"但未登记的名字,用来展示守卫会把这类幻觉挡下来。
  5. 结尾说明原因(EDR 侧 ProgID 官方未公开)——把机制与依据一起交代,避免读者以为这是保守过头的规则。

三、常见报错与排查

3.1 Agent 生成了"看起来很像"的 EDR API 名

  • 现象:Agent 给出的脚本里出现形如AspenEDR.Application之类字符串,语义上非常合理。
  • 根因:大模型基于命名规律生成,而EDR 的 ProgID 官方未公开(铁律 EDR-2),规律不成立。
  • 定位手段:用本篇 2.3 节的守卫扫描输出,看该名是否在白名单内。
  • 解法:未登记一律拒绝;要求按第 06 篇在本机取证后再补登白名单。
  • 预防:把守卫作为 Agent 输出的必经环节,而不是事后抽查。

3.2 Agent 给出的变量名在本机不存在

  • 现象:按 Agent 给的变量名去绑链接或写代码,报"变量不存在"。
  • 根因:变量名随表单与版本变化,且 Agent 可能基于"命名直觉"生成。
  • 定位手段:用本篇 2.2 节的search_variables精确检索变量清单(第 04 篇回收)。
  • 解法:以清单为准;未登记则回本机 Variable List 核实。
  • 预防:把变量清单作为 Agent 的必备知识源;检索工具坚持二元返回。

3.3 Agent 直接调用计算工具,把许可吃干

  • 现象:Agent 在循环里反复触发计算,许可被占满。
  • 根因:把"有副作用的工具"与只读工具混在一张清单里下发(违反 19.2 节原则)。
  • 定位手段:检查工具清单里side_effect=True的工具是否默认可见;记录连接耗时看长尾。
  • 解法:有副作用的工具单独隔离,走审批与配额;用第 18 篇的耗时观测判断并发。
  • 预防:allowed_tools()默认只返回只读工具(本篇代码一已实现)。

3.4 Agent 建议"忽略 Operation 告警,继续交付"

  • 现象:Agent 给出的结论里把Operation类告警当作"可忽略提示"。
  • 根因:Agent 未被告知官方三类告警的定义与路由规则;或它把"提示"和"告警"混淆了。
  • 定位手段:检查 Agent 的知识源里是否有第 16 篇的告警路由规则。
  • 解法:把三类告警定义与"Operation阻塞交付"写入系统提示与知识底座;对越界结论直接判为错误。
  • 预防:Operation类判定做成硬规则(第 12 篇的usable闸门),而不是让 Agent 解释。

3.5 把社区 MCP 方案写成了"官方支持"

  • 现象:方案里写"官方支持用大模型操作 EDR/流程模拟"。
  • 根因:混淆了社区实践(D 级)与官方能力。
  • 定位手段:回到证据分级——官方是否发布了该能力的公开材料。
  • 解法:改写为"社区已有此类实践,非官方支持,能力边界受 COM 约束"。
  • 预防:所有涉及 LLM/MCP 的表述先过证据分级检查(第 01 篇纪律)。

四、动手练习

练习 1(工具白名单设计)
用 2.1 节脚本生成工具清单,并回答:如果要给 Agent 增加一个"启动计算"的工具,需要额外加什么防护。判定标准:默认允许清单必须不含任何side_effect=True的工具;对"启动计算"工具必须给出至少三项防护(人工审批、配额上限、连接耗时观测);并说明把它与只读工具混发的风险。
常见错误做法:为了方便,把计算工具也放进默认清单。为什么错:它是一把"随时能消耗许可的钥匙",一旦 Agent 进入循环就会吃掉许可池,影响所有使用者。

练习 2(二元检索压制幻觉)
用 2.2 节脚本检索一个不存在的变量名与一个不存在的告警类型。判定标准:两次都必须返回found: False,且reason必须给出"下一步动作"(回收清单 / 补录经验);不得返回任何"最相近"的记录。同时说明为什么二元返回比近似返回更能压制幻觉。
常见错误做法:让检索工具返回"最相似的 3 条"。为什么错:近似结果会诱导模型把"相似"当成"事实",而幻觉的典型形态正是"语义合理但事实不存在"。

练习 3(输出守卫拦截)
用 2.3 节脚本扫描一段含Apwn.Document与一个自造 EDR 名(如Xxx.Application)的文本。判定标准:Apwn.Document必须被列为允许且标注"官方已核验"并给出来源;自造名必须进拒绝清单并提示"以官方文档为准或按第 06 篇取证后补登";最终必须给出"未登记名不得进入可执行脚本"的结论。
常见错误做法:只警告不拒绝。为什么错:警告会被忽略;只有拒绝才能强制流程回到"取证或查官方文档"这条正路。

五、小结与下一篇预告

小结:让大模型 Agent 参与 EDR 工作的唯一安全范式是**“只读查询与建议 + 写操作与设计判断过人工闸门”。Agent 的安全能力集中在"数据面的自然语言检索入口 + 报告草稿生成";危险动作包括直接提交计算、代做设计判断、越过Operation告警判定、编造 API 名、改写结果与日志。工程上有三件配套机制:工具白名单(默认只读,把"启动模拟器"这类有副作用的工具单独隔离并走审批与配额)、知识底盘(变量清单 + 告警经验库 + 交付记录 + 环境档案,全部是"本机事实 + 出处",且检索坚持命中/未命中二元返回**以压制幻觉)、输出守卫(白名单分"官方已核验"与"本机取证"两级,未登记的App.Object形态字符串一律拒绝)。必须保留人工闸门的动作是Accept Design、处置Operation告警、切换默认 EDR 版本、定义目标函数与权重、设定报警阈值——因为它们的"正确答案"依赖工程判断。最后,关于 MCP:官方未公开面向 EDR/流程模拟的 LLM 或 MCP 支持,社区确有此类实践但属D 级,表述时必须写成"社区做法、非官方支持"。

下一篇预告(20|收官:企业级批量换热器设计与校核平台):把前十九篇的零件装配成一个完整项目——平台的四层架构(数据源层 / 计算层 / 判定层 / 交付层)、统一 CLI 与配置、模板与变量清单管理、批量与断点续跑、告警分诊与经验库、结垢监控与闭环优化、多版本与许可治理,以及一套可验收的交付物清单;末篇是综合全系列知识的完整实战项目,不再是概念综述。


本篇认知问题回显(FAQ)

Q1:大模型 Agent 在 Aspen EDR 自动化里能帮什么忙?

A:最佳定位是"数据面的自然语言检索入口 + 报告草稿生成器"——例如查询某台设备的时间序列趋势、检索某类告警的历史处置、解释某条结果为何usable=False、基于结构化结果生成报告草稿;这些都是只读、可复核的工作。

Q2:哪些能力做成工具交给 Agent 是安全的?

A:默认只暴露只读、无副作用、输出结构化且带出处的工具;任何会启动模拟器并占用许可的工具(如触发计算)必须单独隔离并走人工审批与配额,不能与只读工具混在一张清单里下发。

Q3:怎么把已有资产变成 Agent 的知识底盘?

A:用四类资产——变量清单(回答"哪个变量名是真的")、告警经验库(带source的处置经验)、交付记录(含usable与三类告警计数)、环境档案(回答"在什么环境下产生");它们共同特征是"本机事实 + 出处",这正是压制幻觉的边界。

Q4:怎么用机制挡住 Agent 编造 EDR API 名?

A:用输出守卫——维护分两级(官方已核验的流程侧 ProgID、本机取证的 EDR 相关名)的白名单,扫描输出中所有形如App.Object的字符串,未登记的一律拒绝进入可执行脚本并提示"以官方文档为准或按取证流程补登";机制上"未登记即拒绝"比"未登记即警告"更有效。

Q5:MCP 这类接口在 EDR 自动化里的现状如何?

A:官方未公开任何面向 Aspen EDR(及流程模拟)的 LLM 或 MCP 支持;社区存在通过 COM 让大模型操作模拟软件的项目,但属D 级社区做法、非官方支持,其能力边界受 COM 约束(需本机授权 Windows 安装、ProgID 未公开等),方案里不得写成官方能力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询