xlyAi Agent 架构报告

印刷 ERP 智能助手 —— 单 ReAct Agent · 技能驱动 · 模型全只读 · 人在环写入

依据 agent-main 分支当前代码编写,与设计文档不一致处以代码为准。

Java / LangChain4j 本地 27B 模型(数据不出网) MySQL + Redis 7 个工具 · 5 项技能 2026-07-29
PART 1

Agent 的设计

xlyAi 是 ERP 之上的「理解与编排」层:听懂业务人员的话,替他们在 1700 多张表单里查数、看单、发起操作。它是一个智能体(无路由、无意图分类),且模型本身没有任何写入能力——改数据的永远是人的一次点击。

1.1 四条设计立场

① 单智能体,自己决定怎么做

所有对话进同一个 ReAct 循环,模型自行决定查数、澄清、载入流程还是出卡。不设意图门——实测无准确率收益,反而在分类环节丢失原话信息。

② 模型全只读,写入是人的动作

模型最多把写操作渲染成一张带按钮的卡片,然后停下;真正写入走用户点按钮后的确定性路径,不经过模型。幻觉在结构上碰不到数据。

③ 知识外置:流程是数据,不是代码

业务流程写成技能文本存在数据库里,模型按需载入照做;改流程不用改代码发版。领域结构(域、表单、字段)来自离线物化的知识图谱。

④ 薄层:业务权威永远在 ERP

读走 ERP 与网页相同的 API,写只投递到一张队列表由 ERP 执行。AI 层不复制业务规则,越薄越不会与 ERP 真实行为漂移。

1.2 Agent 解剖

大 脑 · 知 识 · 能 力 · 记 忆 · 边 界
知识
业务域地图11 个域及流转,常驻提示词
技能库流程 playbook,按需载入
知识图谱表单目录 · 字段字典
大脑 + 循环
本地 27B 模型(低温度)
ReAct 工具循环自选工具与时机,最多 8 步
唯一 system prompt角色+域地图+技能索引+硬规则
确定性护栏反编造重试 · 谎报纠正
能力(全部只读/只渲染)
查:找表单 · 读数据 · 查记录
问:澄清小问题(可点选项)
请求核准:弹表单 / 出预览卡出卡即停,等人点按钮
记忆
会话事件账本(唯一事实源)
按 token 预算投影成上下文(见 2.3)
边界
身份:ERP token 透传 + 服务端内省,失败即拒
权限:表单级白名单 + 租户隔离,随每次调用注入

权限不是模型要遵守的规则,而是注入在每个工具里、它无法越过的边界。

1.3 一轮对话的生命周期

用户发话自由文本
确定身份token 换真实身份与权限
失败即拒
组装上下文提示词 + 流程卡 + 记忆投影
ReAct 循环载技能 / 查数 / 澄清 / 出卡
护栏检查没查数报数字→重试
谎称已保存→纠正
收尾给出答复,或出卡即停

全程流式推送;每个事件按序落入账本,成为下一轮记忆。用户点了卡片按钮,则进入第二部分的确定性写路径。

1.4 能力面:七个工具,四种角色

工具集固定且极小:所有轮次共用同一组 7 个工具与同一份提示词。能力面越小,小模型的工具选择越稳,提示前缀稳定也利于推理缓存。
角色工具做什么 / 为什么
载入流程useSkill载入某技能全文。提示词只放一行索引,全文按需加载;载入后钉在流程卡上跨轮生效。
感知查数findForms「某类单据」→ 具体哪张表单。模型不必背 1748 张表结构。
readFormData读某表单一页数据(可过滤、翻页)。答案里的每个数字都必须出自这里,输出截断分页。
lookupRecord某条命名记录的完整字段。多条命中报候选让用户挑,不猜。
对话交互askUser一个澄清问题 + 可点选项。缺关键信息才问、一次问全、问完即停。
请求核准collectForm新增:弹一张表单让用户一次填齐;已说的值预填,客户/产品从真实数据下拉选。
previewChange改/作废/审核等:出预览卡(当前值 + 变化高亮 + ERP 同名按钮)。人核对的就是将要写入的。

1.5 知识体系三层

域地图(常驻)

11 个业务域及上下游流转,每域一行常驻提示词——给模型一张「问题落在哪」的粗地图。

技能(按需载入)

每篇只写步骤与停止条件,不写错例枚举。内置五篇:查询、新建报价、新建单据、修改记录、单据状态操作。

知识图谱(工具背后)

从 ERP 元数据物化的表单目录与字段字典(中文名⇄技术列⇄外键)。模型不直接看它,但每次定位与解析都踩在它上面。

1.6 环境

浏览器
聊天流 + 卡片/表单/选项片
多命名会话侧栏
流式对话
ERP 登录态透传
xlyAi(本报告主角)
单 ReAct Agent
确定性保存端点(人在环写)
授权层(补 ERP 缺失的表单级权限)
只读 API
+ 共享队列表
ERP 后端(业务权威)
表单读 API · 身份内省 · 字段候选
写操作执行器 + AI 待办 + 状态回执

支撑设施:MySQL(与 ERP 共库,多租户)、Redis(缓存/暂存)、本地 27B 模型(OpenAI 兼容通道)。接口细节见第三部分,实现映射见附录。

PART 2

核心机制

支撑上述设计的四条机制:写路径的层层闸门、事件账本记忆、以及针对小模型不可靠性的确定性护栏。

2.1 编排:技能文本代替路由与流水线

  • 规则只有一条:全部自由文本进唯一 ReAct agent,流程知识由模型按需 useSkill 载入。
  • 不做意图门:分类器不掌握字段定义,抽取必有损(「大16开」→「16开」);原话只应在字段定义存在的地方被解释一次。
  • 跨轮续办靠流程卡:激活的技能全文钉在提示词尾部,流程终结才摘下——旧轮被压缩也不丢步骤。

2.2 写路径:三道闸

LLM 说什么都改不了数据库。能写的只有两个确定性端点,且最多写一行待办——执行在 ERP 侧。
以「修 改 记 录」为 例
用户「把 XX 单数量改成 3000」
模型(只读)载技能 → previewChange
闸① 预览卡定位 + 校验
解析产物暂存服务端
模型停手等用户核对
用户点【保存】
闸② 确定性端点归属/权限重查 → 重读记录重校验
→ 原子抢占防重复提交
闸③ 入队ai_op_queue 一行 pending
ERP 执行报价自动执行
其余进待办

所见即所写

保存时重读记录:被他人改过的值、变了的审核/作废状态一律拒绝,请重新预览。卡上显示的 FK 是实际解析绑定的记录名、数字是规范化后的值——人核对的就是入库的。

状态合法性硬检查

审核要求未审核、作废要求未作废等前置条件在预览与保存各查一次,ERP 执行时刻再查一次,三层防竞态。

新增走表单

用户填完点保存后由端点构建载荷:中文名→列、FK 名称→id、类型强转(解析不了的数字报错而非写 0)、补必填默认、生成主键与单号。报价单构建主表+从表+多数量三张表,价格留给 ERP 核价。

防重复防并发

previewId 一次性、原子抢占,并发点击只有一个能入队;多字段先全部过校验再单事务入队,绝不写一半。

2.3 记忆:事件账本 + 四段投影

会话没有可被并发覆盖的「聊天记录数组」:每句话、每次工具调用、每次按钮点击都是一条追加事件,落 MySQL(Redis 热缓存)。前端历史与 LLM 上下文是同一账本的两种投影,永不对不上。喂给模型的上下文按 token 预算分段组装:

① system prompt永不让位
② 进行中的流程卡激活技能 + 在办单据状态永不让位
④ 往事摘要区预算外旧轮 → 每轮一行确定性摘要小额预算
⑤ 近期原文区整轮纳入,旧轮工具结果压成短摘要预算内尽量装
当前轮原样保真,超限时先压最早的工具结果永不让位

发送前自检总量,超了继续收缩——绝不让推理端从头部静默截断(那样 system prompt 先死)。估算故意偏高,并与模型返回的实际 token 数持续对账。

2.4 针对小模型的确定性护栏

反编造

零工具调用却答出数字 → 注入纠正话术自动重试一次;复发则标注「未经核实」。

谎报纠正

声称「已保存/已完成」但本轮没出过卡 → 追加提示「没有卡片即没有任何写入」。

确定性解析

尺寸拆分(「50*30*5」→长/宽/高)、数字/日期强转、FK 消歧、单号生成全在代码层——模型负责理解意图,代码负责解释取值。

资源护栏

工具循环最多 8 步、超时 180 秒、所有工具输出分页/截断。

2.5 安全红线

不变量一句话
身份 fail-closed身份只来自 ERP 服务端内省;token 无效即 401,绝不回落管理员身份。
token 不进模型用户 token 仅单次请求持有,绝不进提示词、账本、暂存。
表单级白名单读/写/下拉共用同一权限边界;鉴权参数用服务端反查值,不信模型自报。
租户隔离所有查询强制品牌谓词,拿不到租户宁可返回空。
会话隔离会话 id 强制用户命名空间——伪造他人 id 只会落到自己名下。
注入防护URL id 白名单校验、SQL 全参数化、CORS 白名单。
读不变写读接口只传分页/过滤参数,绝不透传 ERP 存在的写类参数。
PART 3

AI 侧 ⇄ ERP 侧:协作与接口

分界线一句话:xlyAi 负责理解、定位、校验、请求核准;ERP 负责执行、审计、权属、回执。交接靠同步的薄 HTTP 接口 + 异步的共享队列表。

3.1 HTTP 接口(xlyAi → ERP,全部透传用户 token)

接口用途
GET /ai/whoamitoken → 服务端认定的身份与租户,所有端点的身份唯一来源。
POST /business/getBusinessDataByFormcustomId表单数据读取,与网页前端同一接口,天然带租户与行级权限。
GET /getUuid新增载荷的主键由 ERP 发号。
POST /business/checkBusinessDatadry-run 预检:复用 ERP 真实校验链、强制回滚,把「保存了才发现不合法」提前。
POST /ai/fieldOptionsFK 下拉候选,按 ERP 下拉配置取——带行级权限、级联过滤、联动回填;不可用时回落本地字典。

3.2 ai_op_queue:交接面与状态协议

用户点按钮后 xlyAi 写一行操作请求(类型 + 目标 + 载荷 + 描述),状态恒为 pending+100;领取、执行、幂等、审计、回写全在 ERP 侧。现行策略:报价自动执行,其余进「我的 AI 待办」。xlyAi 只把状态只读展示在流程卡上,绝不重复提交。

pending100 已提交(xlyAi 唯一写入)101 ERP 处理中
success200 成功 · 201 幂等命中
/
fail400 载荷 · 401 权限 · 404 不存在 · 409 状态冲突422 业务校验 · 423 锁定 · 450 取消 · 500/504
  • xlyAi 只写 pending+100,其余状态只由 ERP 回写。
  • 一次保存多字段 = 多行待办(单事务);ERP 执行时刻再验状态,冲突回 409。
职 责 分 界
xlyAi
理解意图 · 载入技能 · 定位表单与记录
校验:字段/类型/FK/权限/状态/租户
渲染卡片,等人点按钮
入队 pending —— 到此为止
ai_op_queue
ERP 侧
执行器以用户身份复用 ERP 原生写入/审核逻辑
幂等 · 执行时刻校验 · 单号执行前重新生成
审计留痕 · 状态回写 · AI 待办入口

3.3 身份与授权协作

凭证透传,不自造身份

xlyAi 不签发、不存储、不续期任何用户凭证:前端逐请求带 ERP token,xlyAi 原样转发。会话按稳定身份存,重登录换 token 后历史接得回。

授权互补

ERP 后端只强制租户 + 行级两层,表单级权限校验处于关闭状态(仅前端 UI 用)。xlyAi 用同一份权限数据在自己侧补回这层,作为纵深防御;根因整改待业务决策。

PART 4

质量保障 · 残余风险 · 设计取舍

4.1 质量保障

基准评测

50 题冻结基线 + 多轮轨迹基准(消歧/接续/夹带/回指),与生产读同一份提示词和技能文件。当前:扩展集 12/12,全轨迹 84%。

单元测试

8 个测试类钉住不变量:fail-closed、会话归属、投影正确性、并发不丢事件、强转拒非法值等。

对抗性审计

多智能体并行审计 + 独立复核证否,最近一次全量复审 CRITICAL 0 / HIGH 3,HIGH 已全部修复回归。

可观测性

每次 LLM 调用记录耗时/token/错误,估算与实际 token 持续对账;可选导出自托管 Langfuse(数据不出网)。业务审计随执行权在 ERP 侧。

4.2 残余风险(交付说明)

级别事项一句话
安全技能表是提示词注入面谁能写 ai_skill 谁就能改 agent 行为,需收紧表写权限。
安全dry-run 失败放行刻意取舍:预检挂了不挡用户,ERP 执行时仍会真校验。
安全token URL 通道 / 生产前置校验壳层嵌入的 token 传递与 nginx 前置会话校验属环境决策项。
运维账本永久保留append-only 永不删除,需定保留/归档策略。
协作队列旧列待删 / 生产迁移待执行等 ERP 去掉兼容读后删列;4 份迁移 SQL 待上生产。
协作「处理中」卡死无恢复ERP 领取后异常退出会停在 101,需 ERP 侧超时补偿。
根因ERP 权限根因未整改xlyAi 的白名单是纵深防御,不替代后端重开表单级校验。
功能无语义召回表单定位全靠关键词匹配,模糊说法要换词重试。
功能策展字段仅报价有其他复杂主-从单据的新增走字典启发式,体验有限。

4.3 贯穿全局的取舍

  • 不引编排框架:人在环用「出卡即停 + 确定性端点」实现,比中断/续跑机制更简单,也更安全——模型根本没有写工具。
  • 可靠性放代码不放提示词:不写逐案纠错规则,靠确定性解析 + 廉价恢复 + 回归基准。
  • 执行权交出去:AI 止步于入队,写入发生在 ERP 原生路径——代码量与攻击面同时缩小。
  • 处处幂等:所有交接点都假设会被重复触发(一次性抢占、追加原子、幂等键、单号重生成)。

附录:设计概念 → 代码映射

设计概念主要代码位置
ReAct 循环 / 按请求组装agent/ReActAgent · config/AgentFactory · agent/AgentIdentity
对话入口 / SSE / 护栏web/AgentChatController
7 个工具tool/:UseSkillTool · KgQueryTool · ErpReadTool · FormCollectTool · PreviewChangeTool · InteractionTool
提示词 / 技能service/SystemPromptServiceprompts/system.txt)· service/SkillServiceai_skill / skills/*.md
表单/字段/FK 解析校验service/FormResolverService · service/FormRenderServiceviw_ai_useful_forms / viw_kg_field_dict
预览/保存闭环 / 唯一写入口service/PreviewService · web/PreviewController · service/OpServiceai_op_queue
账本与记忆投影service/LedgerServiceai_chat_event)· agent/EventLogChatMemory · service/EventProjectionService
身份与授权 / ERP 客户端service/AuthzService · service/ErpClient
会话 / FK 选项service/ConversationService · web/ConversationController · web/FormController
可观测性config/TracingChatModelListener