AI Agent接入CRM、ERP、文档和消息系统时,API设计、工具调用策略与异常处理机制是决定项目成败的关键。本文从架构视角拆解接口适配、上下文传递、超时与回滚等工程实践。

软件定制开发团队
"真正有价值的技术内容,应该能帮助客户更快判断方向、预算和落地路径。"
企业引入AI Agent,最常见的场景是让它操作现有的CRM、ERP、文档系统和消息平台。但多数项目在集成阶段就卡住了——不是因为AI模型不够聪明,而是因为Agent与业务系统之间的接口、权限、数据格式和异常处理没有提前设计好。
我参与过几个将Agent接入Salesforce、用友U8和飞书的项目,得出的结论是:Agent接入的本质不是把API暴露给LLM,而是构建一个“可控的、可回滚的、可审计的”工具调用层。这篇文章会从接口适配、工具注册、上下文传递、超时与重试、异常回滚五个维度展开,最后给出一个生产级的接入检查清单。
企业系统通常分三类:有标准REST API的(如Salesforce、HubSpot)、有SOAP或老旧API的(如SAP ECC、用友NC)、以及根本没有API的(如部分自研Excel报表系统、老版OA)。AI Agent必须能统一处理这三种情况。
如果目标系统有REST API,Agent接入相对简单。但有一个容易忽略的问题:API的速率限制和分页策略。Salesforce的API限制是每天15,000次请求(Developer版),而Agent在自动执行批量查询时,可能几分钟内就耗尽配额。解决方案是在Agent的调用层做限流——不是依赖LLM自己控制,而是在工具函数内部实现令牌桶或滑动窗口。
```python
class RateLimiter:
def __init__(self, max_calls, period):
self.max_calls = max_calls
self.period = period
self.tokens = max_calls
self.last_refill = time.time()
def allow(self):
now = time.time()
elapsed = now - self.last_refill
self.tokens = min(self.max_calls, self.tokens + elapsed * (self.max_calls / self.period))
self.last_refill = now
if self.tokens >= 1:
self.tokens -= 1
return True
return False
```
这个限流器需要在Agent调用任何外部API之前执行。如果限流失败,Agent应该返回“当前请求受限,请稍后重试”而不是让LLM自己猜测。
很多ERP系统(如SAP、Oracle EBS)仍然使用SOAP协议。SOAP的XML结构复杂,LLM直接生成SOAP请求的错误率极高。我的建议是:在Agent和SOAP系统之间加一个“协议转换层”——将SOAP请求封装成REST风格的接口,由转换层负责XML序列化与反序列化。
转换层需要处理几个问题:
没有API的系统,Agent只能通过“模拟操作”来接入。常见做法是:部署一个RPA(机器人流程自动化)工具,让Agent通过RPA操作UI。但这里有一个关键风险:UI变化会导致Agent无法工作。
我见过一个项目,Agent通过Selenium操作金蝶K3,结果金蝶更新了一个补丁,界面上一个按钮的ID变了,Agent连续三天无法执行采购订单审批。后来我们改为:让RPA工具暴露一个“操作队列”接口,Agent只向队列发送意图(如“审批采购单PO-2024-001”),RPA工具自己处理UI适配。这样即使UI变化,只需要修改RPA脚本,不需要重新训练Agent。
Agent调用系统功能的方式,本质上是LLM从一组“工具”中选择并执行。工具的定义质量直接决定了调用成功率。
每个工具(API、函数、RPA操作)都需要注册到Agent的“工具库”中。注册时提供的描述信息,决定了LLM能否正确选择工具。描述应该包含:
一个常见的错误是描述太模糊。例如“查询客户信息”这个描述,LLM可能用它来查询任何客户相关的信息,但实际工具只能按客户ID查询,不支持按姓名模糊查询。正确的描述应该是“根据客户ID(精确匹配)获取客户详细信息,包括联系人、地址和信用额度”。
参数校验必须在工具函数内部执行,不能依赖LLM。LLM生成的参数可能包含SQL注入、路径遍历或越界值。例如,Agent调用“delete_customer”工具时,如果LLM生成的customer_id是“1 OR 1=1”,工具函数必须拒绝执行。
校验策略:
我在一个项目中遇到的情况是:Agent连续两次调用“create_order”工具,因为第一次调用的响应超时,LLM认为失败又调了一次,结果同一个订单被创建了两次。后来我们在工具函数中加入了“请求ID去重”——每次调用携带一个唯一请求ID,工具函数检查该ID是否已被处理过。
Agent在调用多个工具时,需要传递上下文。例如,先创建客户,再创建订单,订单需要引用客户的ID。如果Agent没有维护上下文,第二次调用时LLM可能忘记客户ID,导致参数错误。
解决方案是:在Agent的会话中维护一个“上下文缓存”,每次工具调用成功后,将返回的关键字段(如ID、状态码)存入缓存。LLM在生成后续调用时,从缓存中读取这些值。缓存的生命周期应该与当前会话绑定,会话结束后自动清除。
上下文传递不只是参数缓存,还包括用户意图、业务规则和操作历史。
当用户说“帮我查一下上个月销售额超过100万的客户,然后给他们发邮件通知”,Agent需要先查询客户列表,再发送邮件。如果查询结果为空,Agent应该直接返回“没有符合条件的客户”,而不是尝试发送邮件。
意图上下文需要在Agent的提示词(prompt)中明确传递。一种做法是:在每次工具调用后,将“当前状态”更新到提示词中。例如:
```
当前状态: 已查询客户列表,结果为空。下一个动作: 无需发送邮件,直接返回结果。
```
这听起来很简单,但实际项目中很容易遗漏。尤其是在Agent调用多个工具时,LLM可能忘记之前的查询结果。我建议在Agent框架中实现一个“状态机”,每个工具调用对应一个状态转移,状态机确保Agent不会跳过必要步骤。
不同系统有不同的业务规则。例如,CRM中创建联系人时,邮箱地址不能重复;ERP中创建采购单时,供应商必须有有效合同。这些规则很难通过LLM的自然语言理解来保证。
我的做法是:在工具函数内部实现业务规则校验,而不是依赖LLM。工具函数应该返回明确的错误码和错误信息,Agent根据错误信息决定下一步操作。例如,如果创建联系人时邮箱重复,工具函数返回“EMAIL_DUPLICATE”错误,Agent可以提示用户“该邮箱已存在,请确认是否使用其他邮箱”。
Agent的操作历史应该记录到日志中,方便审计和回滚。每条操作记录应该包括:操作时间、操作类型、输入参数、返回结果、执行状态。对于关键操作(如删除、修改金额),还应该记录操作前后的数据快照。
日志存储建议使用独立的日志系统(如Elasticsearch),不要与业务数据混在一起。日志保留周期根据企业合规要求设定,一般不少于180天。
企业系统的响应时间不可控。一个ERP的报表查询可能耗时30秒,而Agent的LLM调用通常有5-10秒的超时限制。如果不处理超时,Agent会认为工具调用失败,然后重试或放弃。
建议为每个工具设置独立的超时时间。查询类工具可以设置较长的超时(如30秒),写入类工具设置较短的超时(如10秒)。超时后,Agent应该执行以下逻辑:
1. 记录超时日志,包括调用参数和超时时间点。
2. 不立即重试,而是等待一个“冷却期”(如5秒)。
3. 冷却期后,检查目标系统的状态。例如,调用CRM的“查询订单状态”接口,看刚才的操作是否已经执行成功。
4. 如果操作已成功,返回结果;如果操作未执行,决定是否重试。
这种“先检查再重试”的策略可以避免重复操作。我在一个对接SAP的项目中,Agent在超时后直接重试,结果SAP端成功创建了两个相同的采购单,后续不得不手动删除。后来我们改为先查询再重试,问题就解决了。
重试次数应该有限制,一般不超过3次。重试间隔使用指数退避:第一次重试等待2秒,第二次4秒,第三次8秒。超过最大重试次数后,Agent应该将任务标记为“失败”并通知人工处理。
指数退避的另一个好处是:当目标系统负载过高时,自动降低请求频率,避免加剧系统压力。
幂等性是避免重复操作的关键。对于创建类操作,可以在工具函数中实现“如果记录已存在,返回已有记录ID”的逻辑。对于更新类操作,可以使用乐观锁(版本号)或条件更新(如“仅当状态为待处理时才更新”)。
幂等性设计应该由工具函数保证,而不是依赖Agent的调用逻辑。因为Agent的调用逻辑可能因为网络问题、LLM幻觉等原因出现偏差。
异常处理是AI Agent接入企业系统中最容易被低估的环节。一个异常如果处理不当,可能导致数据不一致、业务中断甚至资金损失。
企业系统中的操作往往是链式的。例如,创建订单涉及:检查库存、扣减库存、创建订单记录、通知物流。如果其中一步失败,之前的步骤需要回滚。
Agent框架需要支持“补偿事务”(compensating transaction)。即,为每个操作定义一个“反向操作”。例如:
补偿事务的执行顺序应该与正向操作相反。如果正向操作是A->B->C,回滚顺序是C->B->A。补偿事务本身也可能失败,需要设计重试机制。如果补偿事务也失败,系统应该将当前状态标记为“不一致”,并触发人工介入。
不是所有异常都需要人工介入。例如,查询超时可能只是网络抖动,Agent可以自动重试。但以下异常应该立即告警:
告警应该发送到企业现有的监控系统(如Zabbix、Prometheus)或消息平台(如钉钉、飞书)。告警内容应该包含:异常类型、涉及的工具、输入参数、错误信息、时间戳和请求ID。
当Agent无法处理异常时,需要将任务转交给人工。转交接口应该包含:
人工介入后,Agent应该暂停当前会话,等待操作员完成处理后再继续。操作员可以选择“继续执行”、“回滚”或“终止任务”。Agent框架需要支持这种“暂停-恢复”机制。
基于以上讨论,我总结了一个AI Agent接入企业系统的检查清单。这个清单不是通用的,但可以作为项目评审的起点:
这个清单中的每一项,在SystemDo参与过的几个企业级Agent项目中都被验证过。特别是事务回滚和人工介入接口,在对接用友U8和Salesforce的两个项目中,直接避免了两次生产事故。
最后,需要强调的是:AI Agent接入企业系统是一个工程问题,不是AI问题。模型的能力在快速提升,但系统的稳定性、可审计性和可回滚性,始终需要扎实的软件架构来保障。如果你的团队正在规划Agent集成,建议先从最小可行集成(MVI)开始,只接入最核心的1-2个工具,验证异常处理流程后再扩展。这样即使出现问题,影响范围也是可控的。
继续了解企业数字化、SEO / GEO、AI 自动化和软件定制开发中的常见问题。