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 的目标是验证一套可落地模式:
- 通过 HTTP Listener 保持统一请求入口。
- 用
langchain4j-agent做意图理解与工具选择。 - 用
langchain4j-tools把业务 API 暴露成可调用工具(新增工具不需要写 Java)。 - 一次响应同时满足“人可读”和“系统可处理”。
本文全部结论均来自仓库内现有路由、配置与运行日志,并结合现有 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
路由中关键处理:
CamelLangChain4jAgentSystemMessage由ai.system.prompt注入CamelLangChain4jAgentMemoryId从请求 JSON 的$.memoryId提取- Body 从
$.message提取为用户输入
随后进入 Agent 端点:
<to uri="langchain4j-agent:{{service.ai.type}}Assistant?agent=#genericAiAgent&tags={{ai.agent.tags}}"/>
3) Tool 路由(纯 XML)
Agent 通过 tags=order-demo 可发现以下 3 个工具:
queryOrderDetailcancelOrderlistRecentOrders
每个工具都通过 langchain4j-tools:* 暴露,并在 URI 中声明:
description:工具语义描述,帮助模型做工具选择parameter.xxx=type:参数名与类型声明,便于自动抽取参数- 下游调用:通过 HTTP 调用 mock 子路由做端到端验证
示例:
<from uri="langchain4j-tools:cancelOrder?tags=order-demo&description=Cancel an existing order by order ID. Requires a reason for cancellation.&parameter.orderId=string&parameter.reason=string"/>
4) 响应回写结构
Agent 执行后,路由通过 DataSonnet 组装统一响应,字段包括:
successmemoryIdresponseText(自然语言回答)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=trueserver.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,并确保 requestCharsetProcessor 与 jsonResponseProcessor 在链路中生效。
总结
AiAgentDemoSrv v1.0.0 给出了一套实用的大模型订单操作基线:
- 一个 HTTP Listener 请求入口
- 一层 Agent 编排
- 多个
langchain4j-tools业务工具 - 一个统一响应回写契约
当业务希望“自然语言驱动操作”,同时又要保留 API 调用可控性和结果可审计性时,这套模式可以直接复用并扩展到真实订单系统。