LightESB AiAgentDemoSrv v1.0.0:用大模型驱动订单数据操作

7 阅读4分钟

TL;DR

  • AiAgentDemoSrv@v1.0.0 对外提供一个 HTTP Listener 入口:POST /api/ai/agent/chat
  • Agent 通过 tags=order-demo 自动发现并调用 3 条纯 XML Tool 路由。
  • 这 3 个工具覆盖查询订单列表、查询订单详情、取消订单。
  • 最终响应同时返回自然语言答复(responseText)与结构化工具数据(toolData)。

元信息

  • 适用版本:AiAgentDemoSrv@v1.0.0
  • 关联服务:AiAgentDemoSrv@v1.0.0@ai-agent-demo-route.xml

背景与目标

在订单类系统里,业务方通常不希望记住 API 路径和字段结构,而是希望直接用自然语言表达意图:

  • “查询张三最近订单”
  • “看一下 ord00xa12 的详情”
  • “帮我取消这个订单,原因是……”

AiAgentDemoSrv 的目标是验证一套可落地模式:

  1. 通过 HTTP Listener 保持统一请求入口。
  2. langchain4j-agent 做意图理解与工具选择。
  3. langchain4j-tools 把业务 API 暴露成可调用工具(新增工具不需要写 Java)。
  4. 一次响应同时满足“人可读”和“系统可处理”。

本文全部结论均来自仓库内现有路由、配置与运行日志,并结合现有 LangChain4j/Camel 使用文档中的组件能力说明整理。

路由与配置说明

1) HTTP Listener 请求入口

来自 lightesb-camel-app/AiAgentDemoSrv/v1.0.0/ai-agent-demo-route.xml

<from uri="undertow:http://0.0.0.0:{{server.port}}/api/ai/agent/chat?httpMethodRestrict=POST"/>

来自 lightesb-camel-app/AiAgentDemoSrv/v1.0.0/common.config.properties

server.port=19095
HTTP.Listener=true

因此入口地址为:

  • POST http://localhost:19095/api/ai/agent/chat

2) Agent 参数与记忆链路

来自 service.config.properties

service.ai.route=true
service.ai.type=orderdemo
service.ai.mode=agent
ai.agent.tags=order-demo
ai.system.prompt=你是一个订单管理助手。你可以帮助用户查询订单状态和取消订单。请用中文回答。
ai.memory.enabled=true
ai.memory.max.turns=10

路由中关键处理:

  • CamelLangChain4jAgentSystemMessageai.system.prompt 注入
  • CamelLangChain4jAgentMemoryId 从请求 JSON 的 $.memoryId 提取
  • Body 从 $.message 提取为用户输入

随后进入 Agent 端点:

<to uri="langchain4j-agent:{{service.ai.type}}Assistant?agent=#genericAiAgent&amp;tags={{ai.agent.tags}}"/>

3) Tool 路由(纯 XML)

Agent 通过 tags=order-demo 可发现以下 3 个工具:

  1. queryOrderDetail
  2. cancelOrder
  3. listRecentOrders

每个工具都通过 langchain4j-tools:* 暴露,并在 URI 中声明:

  • description:工具语义描述,帮助模型做工具选择
  • parameter.xxx=type:参数名与类型声明,便于自动抽取参数
  • 下游调用:通过 HTTP 调用 mock 子路由做端到端验证

示例:

<from uri="langchain4j-tools:cancelOrder?tags=order-demo&amp;description=Cancel an existing order by order ID. Requires a reason for cancellation.&amp;parameter.orderId=string&amp;parameter.reason=string"/>

4) 响应回写结构

Agent 执行后,路由通过 DataSonnet 组装统一响应,字段包括:

  • success
  • memoryId
  • responseText(自然语言回答)
  • toolData(最近一次工具调用返回的结构化 JSON)
  • timestamp

这个返回结构既方便前端展示,也便于日志审计与链路追踪。

请求与响应示例

1) 查询用户最近订单

curl -X POST "http://localhost:19095/api/ai/agent/chat" \
  -H "Content-Type: application/json" \
  -d "{\"memoryId\":\"003\",\"message\":\"查询张三的所有的订单信息\"}"

从运行日志可见:

  • Agent 触发 listRecentOrders
  • responseText 返回订单号、状态、金额
  • toolData 返回结构化订单列表

2) 查询单笔订单详情

curl -X POST "http://localhost:19095/api/ai/agent/chat" \
  -H "Content-Type: application/json" \
  -d "{\"memoryId\":\"001\",\"message\":\"查询订单ord00xa12详情\"}"

日志可见行为:

  • Tool queryOrderDetail 被调用
  • 返回订单状态、商品项、总金额
  • 回答语言遵循系统提示词(中文)

3) 两轮取消订单

第一轮:

curl -X POST "http://localhost:19095/api/ai/agent/chat" \
  -H "Content-Type: application/json" \
  -d "{\"memoryId\":\"002\",\"message\":\"取消订单ord00xa12\"}"

第二轮补充原因:

curl -X POST "http://localhost:19095/api/ai/agent/chat" \
  -H "Content-Type: application/json" \
  -d "{\"memoryId\":\"002\",\"message\":\"七天无理由退货取消订单ord00xa12\"}"

日志验证结果:

  • 第一轮先追问取消原因(toolData=null
  • 第二轮触发 cancelOrder
  • 最终答复明确订单号与取消原因

常见问题与排查

1) Agent 没有调用工具

重点检查:

  • ai.agent.tags 是否与各 Tool 路由 tags 一致
  • description 是否明确描述工具能力
  • parameter.xxx=type 是否完整声明

2) 接口 404 或监听不生效

重点检查:

  • HTTP.Listener=true
  • server.port=19095
  • 请求路径是否精确为 /api/ai/agent/chat

3) Tool 下游调用失败但未抛错

当前 Tool HTTP 调用配置了 throwExceptionOnFailure=false,建议从日志定位:

  • [AI-TOOL] ... httpStatus=...
  • 响应 body 摘要

4) 多轮上下文丢失

重点检查:

  • 多轮请求是否复用同一个 memoryId
  • ai.memory.enabled=true 是否开启
  • ai.memory.max.turns 与 TTL 配置是否符合预期

5) 中文响应乱码

保持 Tool 路由中的 UTF-8 相关 Header,并确保 requestCharsetProcessorjsonResponseProcessor 在链路中生效。

总结

AiAgentDemoSrv v1.0.0 给出了一套实用的大模型订单操作基线:

  • 一个 HTTP Listener 请求入口
  • 一层 Agent 编排
  • 多个 langchain4j-tools 业务工具
  • 一个统一响应回写契约

当业务希望“自然语言驱动操作”,同时又要保留 API 调用可控性和结果可审计性时,这套模式可以直接复用并扩展到真实订单系统。

Links