AI连接SAP实战:OData服务配置与Codex、WorkBuddy、豆包三大接入方案
1. 项目概述与方案选型
1.1 这个项目解决什么问题
先说说背景。很多企业上了SAP之后,业务数据确实都收拢集中了,但问题也来了——业务人员想查个库存、想看看订单状态,还得学事务代码、记各种报表路径。财务月底想跑个报表,IT部门排队排到天荒地老。而另一边,AI大模型已经卷到飞起,Codex、WorkBuddy、豆包这些工具一个比一个能聊,能不能让它们直接跟SAP对话,帮业务人员把数据查出来?
这个项目做的事情很简单: 把AI助手接到SAP系统上,让用户用自然语言问问题,AI通过SAP的接口去查数据、执行操作,再把结果翻译成人话返回给用户。 说白了,就是给SAP装上一个"会说人话的前台"。
我实测下来,Codex、WorkBuddy、豆包这三个都能跑通,只是接入方式各有取舍。后面我会把每种方案的配置细节、踩坑点都写清楚。
1.2 方案选型:RFC、BAPI还是OData
连接SAP的方案,市面上主流的就三条路:
- RFC/BAPI :SAP的老牌接口方式,稳定、功能全,但需要从ABAP侧编写函数,配置比较重,适合企业内部高权限场景。
- OData服务 :SAP Gateway(网关)的标准姿势,配置相对轻量,权限可控性好,适合对外开放或者接第三方平台。
- 直连数据库 :最粗暴的方式,直接把SAP底层的HANA或者Oracle表暴露出来让AI读。这种方式我极度不推荐在生产环境用——绕过业务逻辑直接读数据,脏数据、权限失控、锁表,哪个坑都能让你加班到怀疑人生。
我的建议是: 如果是企业内部项目,优先走OData服务;如果涉及大量自定义业务逻辑,老老实实封装BAPI。 两者都支持HTTP调用,AI平台接入最顺滑。
1.3 适合谁来参考
这篇文章适合三类人:
- SAP Basis/ABAP开发 :负责SAP端的接口搭建、权限配置,可以直接照抄配置步骤。
- 企业架构/数据团队 :想搞"AI+ERP"场景,需要了解方案选型和落地路径。
- AI应用开发者 :手里有Codex、豆包这类AI平台,想接企业数据源,可以参考集成模式。
如果你是这三类之外的读者,也没关系,文章里的思路和踩坑经验是通用的—— 任何AI接业务系统的项目,核心逻辑都差不多:接口怎么暴露、权限怎么控制、上下文怎么管理。
2. SAP端接口准备:AI连接的地基
2.1 OData服务创建全流程
要让AI稳定地连上SAP,地基必须打牢。我用的是SAP Gateway(事务代码SEGW)创建OData服务的方式。大体流程如下:
第一步:定义数据模型
在SEGW里创建一个新项目,定义实体类型(Entity Type)和实体集合(Entity Set)。比如我要暴露一个"库存查询"服务,就定义Material(物料)、Plant(工厂)、Stock(库存数量)这几个字段。这里要注意字段命名规范和类型选择,后面AI解析参数是否顺畅,很大程度上取决于这一步。
第二步:生成运行时对象
定义好模型后,直接生成运行时对象,会自动创建出DPC(Data Provider Class)和MPC(Model Provider Class)两个类。我们需要在DPC的
GET_ENTITYSET
方法里写数据查询逻辑,调用底层的BAPI或者直接读视图。
第三步:注册服务并激活
在
/IWFND/MAINT_SERVICE
事务代码里添加这个服务,勾选"系统别名"(比如
LOCAL
代表当前系统),激活即可。激活后可以用
/IWFND/GW_CLIENT
测试,确认返回的JSON/XML格式正确。
这里分享一个我的实测经验: OData服务暴露的字段一定不要图省事把整张表全拖上去,只暴露AI需要的最小字段集。 原因有两个:
- 数据越少,AI的token消耗越低,响应越快;
- 安全边界更清晰,AI能查什么不能查什么,在数据模型层就卡死了。
2.2 创建核心数据服务:生产订单状态查询
以我实测的"生产订单状态查询"为例,完整配置步骤如下:
数据模型定义(MPC类关键代码):
METHOD define.
DATA: lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_entity_type.
" 创建实体的主键属性
lo_entity_type = model->create_entity_type(
iv_entity_type_name = 'ProductionOrder'
iv_source_entity_set_name = 'OrderSet'
).
" 添加字段
lo_entity_type->create_property(
EXPORTING
iv_property_name = 'OrderNo'
iv_is_key = abap_true
iv_ordertype = 'Edm.String'
).
lo_entity_type->create_property(
EXPORTING
iv_property_name = 'Status'
iv_ordertype = 'Edm.String'
).
lo_entity_type->create_property(
EXPORTING
iv_property_name = 'PlannedQty'
iv_ordertype = 'Edm.Double'
).
ENDMETHOD.
数据获取逻辑(DPC类关键代码):
METHOD GET_ENTITYSET.
" 调用标准BAPI读取生产订单信息
CALL FUNCTION 'BAPI_PRODORD_GET_LIST'
EXPORTING
iv_order_number = iv_order_no
IMPORTING
et_orders = lt_orders.
" 将BAPI返回结构转换为OData输出格式
LOOP AT lt_orders INTO ls_order.
APPEND INITIAL LINE TO et_entityset ASSIGNING FIELD-SYMBOL(<fs_entity>).
<fs_entity>-orderno = ls_order-order_number.
<fs_entity>-status = ls_order-order_status.
<fs_entity>-plannedqty = ls_order-planned_quantity.
ENDLOOP.
ENDMETHOD.
这一步的 关键点 是:BAPI返回的数据结构往往是嵌套的、有多个层级的,必须在此处做好"压平"处理,转换成flat的实体结构。否则后面AI平台解析时会出各种奇怪的问题,最常见的就是"字段存在但取不到值"。
2.3 OAuth 2.0权限配置
SAP系统内部有权限对象(PFCG),但AI平台通过OData调用时,走的是OAuth层面的授权。我建议用SAP Gateway的OAuth 2.0配置(事务代码
/IWFND/IWSG
):
- 创建OAuth客户端ID,绑定到具体的通信用户。
-
指定授权范围(Scope),
精细到服务级别
。比如
ai_inventory_query只能查库存服务,ai_order_query只能查订单服务,严禁用一个万能Scope。 - 设置Token过期时间,默认3600秒,按需调整。
实际踩过的坑
:AI平台调用时,OAuth的Token端点(Token Endpoint)需要从SAP的
/IWFND/CLIENT_REGISTRY
里拿准确的URL,这个URL格式因SAP版本不同有差异。我一开始对接WorkBuddy时,Token端点少写了一层路径,导致每次调用都401。最后抓包对比发现是
sap
这个路径段的问题。
安全提示 :日常运维中,OAuth客户端密码要至少90天轮换一次,并且严禁把客户端密钥硬编码在AI平台的提示词、代码或公共配置里。一旦泄露,等于把SAP的数据接口大门钥匙交给了别人。
3. AI平台接入实操:Codex、WorkBuddy、豆包
3.1 Codex接入SAP
Codex是OpenAI推出的编程智能体,支持Assistant API,可以定义tools(工具),让模型自主决定何时调用外部函数。把SAP的OData服务封装成一个tool,是Codex接入的标准做法。
核心配置(Python示例):
from openai import OpenAI
import requests
import json
client = OpenAI(api_key="your_api_key")
# 定义SAP查询工具
tools = [
{
"type": "function",
"function": {
"name": "query_sap_inventory",
"description": "查询SAP系统中的物料库存情况。当用户询问库存、物料数量、可用量等问题时调用此工具。",
"parameters": {
"type": "object",
"properties": {
"material": {"type": "string", "description": "物料编号,如1000-0012"},
"plant": {"type": "string", "description": "工厂代码,如1000"}
},
"required": ["material", "plant"]
}
}
}
]
def call_sap_odata(material, plant):
"""通过OData服务查询SAP库存"""
url = f"https://sap-gateway.example.com/sap/opu/odata/sap/ZAI_INVENTORY_SRV/InventorySet"
params = {"$filter": f"material eq '{material}' and plant eq '{plant}'"}
headers = {"Authorization": "Bearer " + get_sap_token()}
resp = requests.get(url, params=params, headers=headers, verify=False)
return resp.json()
# 对话主循环
def chat_with_sap(user_message):
messages = [{"role": "user", "content": user_message}]
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=messages,
tools=tools,
tool_choice="auto"
)
# 若模型决定调用工具
if response.choices[0].message.tool_calls:
tool_call = response.choices[0].message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
sap_result = call_sap_odata(args["material"], args["plant"])
# 将结果回传给模型生成自然语言回复
messages.append(response.choices[0].message)
messages.append({
"role": "tool",
"content": json.dumps(sap_result),
"tool_call_id": tool_call.id
})
final_response = client.chat.completions.create(
model="gpt-4-turbo",
messages=messages,
tools=tools
)
return final_response.choices[0].message.content
return response.choices[0].message.content
Codex接入的关键经验 :
- 工具描述写得越细,模型越不容易选错工具。 我一开始的description只写了一句"query SAP inventory",结果模型经常在用户问订单状态时也去调库存接口。后来把每个工具描述写成"当用户提到xxx关键词/在xxx场景下调用"的格式,准确率显著提升。
- SAP返回的数据往往包含大量字段,但一次对话模型只需要其中几个。 我建议在工具返回前,先做字段裁剪,只保留用户问题相关的字段,减少token消耗,也给模型减负。
- 模型输出的工具参数格式偶尔会不标准。 比如物料编号中间有零散的空格、引号,Codex偶尔会忘记转义。我加了参数清洗环节,对字符串参数做strip和格式化校验,问题基本消除。
3.2 WorkBuddy接入SAP
WorkBuddy走的是另一种路线——它本身就是一个"智能体编排平台",提供了可视化的Workflow配置界面,不需要像Codex那样写主循环代码。如果你公司里用的AI平台是WorkBuddy或其他类似的智能体平台,接入SAP的完整配置逻辑是:
- 创建自定义API节点 :在Workflow里添加一个HTTP Request节点,Method选择GET,URL填OData服务的查询端点。
- 配置鉴权 :WorkBuddy支持OAuth 2.0 client credentials模式,把SAP Gateway申请的Client ID和Client Secret填进去,指定Token URL即可。这一步配置正确后,WorkBuddy会自动处理Token的获取和刷新。
- 定义输入输出参数 :明确这个API节点的Input参数(比如物料号、工厂),Output参数(比如库存数量、可用量),后续AI对话流程就可以引用这些参数。
- 将节点接入对话流程 :把API节点挂到意图节点(Intent Node)后面,当用户触发"查库存"意图时,WorkBuddy自动执行API调用,并把结构化结果传给大模型生成回答。
与Codex方案的对比 :
| 对比维度 | Codex方案 | WorkBuddy方案 |
|---|---|---|
| 配置方式 | 代码实现 | 可视化编排 |
| 灵活性 | 高,可任意改造 | 中等,受平台能力限制 |
| 上手难度 | 需一定编程能力 | 业务人员可上手 |
| 适合场景 | 深度定制、复杂逻辑 | 标准化流程、快速落地 |
3.3 豆包接入SAP
豆包给了另一种选择:它提供了Function Calling的API,与Codex的tools机制类似,但在国内网络环境下部署更方便,适合企业内部部署私有化版本。
豆包接入SAP时,我推荐用"先工具后对话"的架构:
用户输入 → 豆包识别意图 → 调用SAP接口函数 → 获取JSON结果 → 返回自然语言
这里涉及两层开发:
- SAP侧的"函数注册" :把OData服务封装成一个可以被Function Calling调用的OpenAPI Schema。豆包的控制台支持直接导入OpenAPI文件,我建议在导出时生成标准的OpenAPI 3.0格式,字段命名保持和SAP OData一致,减少映射转换。
- 业务侧的"执行逻辑" :Function Calling被触发后,后端接收到参数,组装OData请求并执行,把结果回传给豆包。这里有个细节:豆包对Function返回的结果格式要求相对宽松,JSON即可,但必须严格保证字段名和Schema一致。
实测注意点 :豆包的Function Calling对参数上限有约束,SAP的筛选条件如果特别复杂,建议拆分多个函数。比如"查库存"一个函数、"查订单"一个函数,不要尝试在一个函数里把整个SAP业务逻辑都塞进去。
3.4 三种接入方式对比总结
| 对比项 | Codex | WorkBuddy | 豆包 |
|---|---|---|---|
| 接入方式 | API编程 | 可视化Workflow | Function Calling |
| 核心依赖 | OpenAI API Key | 平台订阅 | 豆包API Key |
| 部署位置 | 海外/国内均可 | 按平台 | 国内友好 |
| 主要优势 | 灵活、可控性强 | 低代码、快速搭建 | 网络稳定、中文理解好 |
| 注意风险 | Token成本高 | 灵活性受限 | 大型参数兼容性待验证 |
我的最终建议 :如果技术团队底子好, 无脑选Codex ,它最大的价值是可以用代码完全掌控整个交互链路——从参数清洗到结果格式化,再到多轮对话中的上下文管理,都能做到极致。如果速度优先、业务迭代快, WorkBuddy 可视化编排能省一半工作量。如果要求数据合规不出境, 豆包私有化 部署是唯一选择。
4. 实操过程与核心环节实现
4.1 端到端联调流程
整个"AI连接SAP"的联调,我把它拆成6个环节,每个环节都有独立的验证方法:
环节一:SAP OData服务可访问性测试
这是最基础的一步。直接用浏览器或Postman访问OData端点的metadata,能返回XML格式的
$metadata
文档就说明服务已暴露且可访问。
GET https://<SAP-Gateway>/sap/opu/odata/sap/ZAI_INVENTORY_SRV/$metadata
注意:URL里的
sap/opu/odata/sap/
是SAP Gateway的标准路由前缀,不同的SAP系统(比如S/4HANA和ECC)会有些许差异,但基本都是这个模式。
环节二:OAuth Token获取验证
在Postman里配置OAuth 2.0 client credentials授权,测试能否拿到Token。能拿到,说明用户、密码、权限范围都是通的。拿不到,优先检查配置好的用户是否分配了足够的PFCG角色。
环节三:AI平台API连通性测试
这一步是指AI平台本身的API Key是否有效。Codex、豆包直接调用对话接口测试,WorkBuddy则测试工作流是否能正常触发。
环节四:AI到SAP的穿透测试
让AI自然语言生成调用参数,再通过它调SAP接口。我建议先问一个非常标准的场景化问题,比如"帮我查一下物料1000-0012在工厂1000的库存",看链路是否完整通。
环节五:异常场景模拟
这是最考验稳定性的环节。故意输入不规范的问题,比如"查一下那个库存"——AI可能会生成不完整的参数,此时后端要有兜底逻辑(比如返回提示"请提供物料编号")。还应该测试SAP宕机或超时的情况,AI能不能给用户一个友好的提示而不是直接报错。
环节六:性能压测
模拟多用户同时通过AI查询SAP,观察SAP Gateway的负载情况和AI平台的响应耗时。这一步往往能暴露 慢查询 问题——SAP的OData服务如果没加好索引,AI场景下每个请求都要全表扫描,性能会很难看。
4.2 上下文管理与多轮对话优化
AI接SAP和多轮对话场景下,一个容易被忽略的问题是 上下文管理 。用户说"查完这个库存,再帮我看看它的订单情况"——这里的"它"指的是之前查询的物料,而AI本身是不知道这个"它"具体是什么的。
建议做法是:
- 在后端保存会话状态 ,维护一个"当前物料"、"当前工厂"的临时变量,每次对话轮次都更新。
- 在工具调用的参数生成阶段 ,向前追溯最近几轮对话,把省略掉的指代补充完整。
- 在AI的System Prompt里明确说明 :"当用户使用'它'、'这个'等代词时,结合上下文历史来判断具体指代对象。"
这个方法实测下来能显著提升多轮对话的准确率。我开发的时候花了一整天在Prompt上下功夫,最后把"指代理解"逻辑写死在Prompt里,效果比完全依赖模型自我推理好得多。
4.3 数据权限与越权防护
企业里最怕的不是AI不会干活,而是AI乱干活——比如一个普通业务员直接问"全公司所有物料的库存",如果OData的筛选条件没限制死,AI就会把所有数据拉出来。
我的做法是 在SAP OData服务层面强制用户维度过滤 :
METHOD GET_ENTITYSET.
" 从OAuth Token中解析当前用户信息
CALL METHOD /iwbep/cl_mgw_util=>get_user_from_token
IMPORTING
ev_user = lv_user.
" 根据用户权限范围,强制追加过滤条件
SELECT ...
FROM marc
WHERE werks IN (SELECT werks FROM z_user_auth WHERE uname = lv_user).
ENDMETHOD.
这样无论AI怎么发挥,SAP服务端都只会返回该用户权限范围内的数据。
4.4 日志追踪与审计
AI操作SAP的每一步都应该留下完整的审计日志。日志最少要包含四个要素:
- 会话ID :哪一次对话触发的操作
- 用户ID :谁问的这个问题
- 参数快照 :AI生成的完整参数(含未清洗前的原始值)
- SAP响应时间 :SAP侧处理耗时,排查慢查询必备
日志存哪?我建议写回SAP应用日志(事务代码SLG0/SLG1),统一纳入企业的日志监控体系,方便和SAP原生事务做关联分析。生产环境排查问题的时候,这套日志体系能节约一半时间。
5. 常见问题与排查技巧实录
5.1 认证与权限类问题
| 问题现象 | 可能原因 | 排查方法与解决方案 |
|---|---|---|
| 每次调用都返回401 | OAuth的Token URL拼写有误 |
核对SAP Gateway的Token端点,注意
sap
路径段
|
| 返回403 Forbidden | 通信用户的PFCG角色缺少权限 | 在SU01中给用户分配对应角色,重新生成Token |
| Token能获取但OData数据空白 | 权限范围未精细到服务 | 在OAuth客户端里授权具体的Scope,而不是用默认全量 |
真实踩坑记录 :我曾在Codex接入时遇到一个诡异问题——Postman测试OData能通,Codex调用却一直401。排查了半天,发现是Codex的HTTP库在发送Token时,把Bearer前缀的格式搞错了,多了一个空格。加了个Header格式化中间件后问题解决。 工具不能全信,遇到问题先用curl裸调一遍,能排除很多"灵异事件"。
5.2 数据格式与解析类问题
SAP返回的数据结构和AI模型的预期差异,是另一个高频雷区。
-
SAP OData的日期格式是
/Date(1700000000000)/,这种格式AI一般不认。需要在后端统一转换成ISO 8601格式,我在实现中对所有DateTime类型字段做了转换封装。 -
SAP的十进制数在JSON里可能是字符串
,比如
"12.50"。如果不处理,AI模型可能在求和、比较时把它当文本,算出来的结果完全跑偏。我在后端把所有数值字段统一parseFloat处理。 - 字段名大小写 :SAP OData默认是PascalCase或者全大写,AI模型的训练数据里更习惯camelCase和snake_case。这里有个取舍:是改SAP侧的属性名还是让AI去适应?我建议在AI平台侧的映射层转换,不要动SAP原生属性名,否则影响其他依赖该OData服务的系统。
5.3 性能与超时类问题
实测下来,AI接SAP最大的痛点是 RTT(往返时间)太长 :AI生成参数要几秒,SAP查询要几秒,AI再生成自然语言又几秒。用户等一个回答可能要15秒以上,体验很糟。
优化方案有三个层面:
- SAP侧加缓层 :对高频查询(如物料库存)增加结果缓存,设置的TTL根据业务实时性要求来定,我一般设5分钟。
-
AI侧精简输出
:限制模型生成的回复长度,比如设置
max_tokens,让回答更简洁生成的耗时也会缩短。 - 异步任务化 :对耗时长的复杂报表类查询,走异步任务——AI先回复"正在查询,预计10秒完成",后台SAP查询完成后推送给用户。实测这种设计在"AI接SAP"的场景里非常实用,用户感知的等待时间大幅缩短。
5.4 排查工具推荐
-
SAP Gateway Client
(事务代码
/IWFND/GW_CLIENT):调试OData服务必备,能直接看到完整的请求/响应报文。 - SWA(SAP Web Application Server日志) :SAP后端报错的第一现场。
- AI平台API调试器 :Codex和豆包的调试面板,能查每次Function Calling的prompt和tool call记录。
- Charles/Fiddler抓包 :当怀疑是中间网络策略或代理拦截时,用抓包工具看完整的HTTP链路。
6. 安全加固与生产落地
6.1 传输层安全策略
AI平台和SAP Gateway之间所有的HTTP通信, 必须走HTTPS 。这只是底线,更重要的策略是:
- IP白名单限制 :在生产环境,SAP Gateway的防火墙规则只放行AI平台出口的固定IP段。
- TLS版本限制 :关闭TLS 1.0/1.1,强制使用TLS 1.2+,避免中间人攻击。
- 内网隔离 :如果AI平台和SAP都在内网,可以考虑跳过外网路径,直接内部域名访问,减少暴露面。
6.2 数据脱敏与敏感字段过滤
AI对话场景下,数据脱敏尤其要重视。SAP的主数据中混有大量敏感信息:客户手机号、银行账号、员工薪资、销售成本。我在OData服务层做了字段级脱敏:
" 在DPC类中,对敏感字段做标记替换
CASE ls_entity-field_name.
WHEN 'BANK_ACCOUNT' OR 'PHONE_NUMBER'.
ls_entity-field_value = '***'.
ENDCASE.
实测中,这个方案比在AI平台的Prompt里写"不要输出敏感信息"有效得多—— 从源头切断,而非依靠模型自觉 。
6.3 监控与告警体系
生产环境上线后,我建议至少配置四个监控指标:
- AI调用SAP的失败率 :连续5分钟超过10%,立刻告警。
- OData服务平均响应时间 :超过1秒的慢查询,需要优化索引或加缓存。
- Token消耗突发增长 :不明原因的Token消耗激增,可能是Prompt结构异常或SAP返回了超大响应体。
- 异常参数访问模式 :比如同一AI账号在短时间内大量查询不同物料,可能说明存在恶意遍历或越权尝试。
这些指标都可以通过SAP Solution Manager或外部监控平台(Prometheus+Grafana)采集。 宁可监控报警多也不要少,AI接入SAP后问题的放大效应非常明显——一个小配置错误可能瞬间扫全表。
6.4 日常运维注意事项
最后整理几条我自己运维过程中踩坑总结出的注意事项:
- SAP系统升级后,务必重新验证OData服务 。SAP Note的更新经常影响Gateway框架,尤其版本升级后接口签名可能有细微变化。
- AI平台的模型版本升级后,要做回归测试 。我之前遇到过一次豆包升级,原本正常的Function Calling参数解析变得不稳定,花了整整一天排查才定位到是模型版本导致的。
- 通信用户的密码变更必须及时同步到AI平台 。这里建议用一个密钥管理服务(比如Vault),避免在多个配置文件里手工更新。
- 定期检查OAuth Token的Scope 。业务变更后Scope可能会需要调整,但顺手清理废弃Scope的习惯一定要有,否则权限越积越多。
7. 结尾心得
这套"AI + SAP"的配置方案,我从前期的方案选型到最后的生产上线,前后花了三周。
坦白说,技术本身并不复杂——OData、OAuth、Function Calling,都是各个领域相对成熟的东西。真正的难度在于 跨领域思维 :你需要懂SAP的权限模型和BAPI规范,还要懂AI平台的工具调用机制和上下文管理,更要在两者之间找到那个最合适的切入点。
我个人最大的体会是: 别指望AI靠一个"万能提示词"就能自动搞定SAP的所有业务。 做得好的AI集成,核心功夫都花在"看不见的地方"——SAP侧的接口字段设计、服务权限细分、数据的预处理,AI侧的参数清洗、上下文轮次管理、缓存策略。这些基础工作做得越扎实,AI的表现就越显得"智能";反之,基础不牢靠,再强的模型也会频频出错。
最后再分享一个小技巧: 版本管理中,把SAP的OData服务定义文件和AI平台的Prompt配置放在同一个仓库里管理。 每次改动都走代码评审流程,这样任何一期修改导致的问题,都可以迅速追溯到是哪一方的变更引起的。我目前采用这个方式后,联调阶段的返工率至少降低了一半。
希望这份指南能帮到你。如果你在接入过程中遇到什么奇怪的问题,欢迎交流。
后记:文中所有代码和配置方案均基于SAP S/4HANA 2023版本和AI平台通用API接口实测,具体环境可能略有差异,请以实际系统为准。
更多推荐



所有评论(0)