易源合一在对话式应用里的位置:意图层与执行层的切分方案
# 易源合一在对话式应用里的位置:意图层与执行层的切分方案
> 接入点:3054-2 / 3054-1 / 3054-3 | 请求方式:POST | 返回格式:JSON(3054-3 为 SSE 分块) | 计费:各 5.5 厘/次,失败不扣费 | 最后实测核对:2026-09-15
## 核心要点
- 易源合一是**单句无状态**的,请求参数只有 `text` 和 `args_list`,没有会话 ID、没有上下文参数。多轮对话的状态必须你自己维护。
- 三种放置方式:意图层前置(3054-2 先分流)、执行层直连(3054-1 一把梭)、流式直连终端(3054-3 推到前端)。
- 实测延迟预算:3054-2 单次 0.70~1.62 秒,3054-1 单次 0.65~2.32 秒,两者串联最坏接近 4 秒。
## 先确定一件事:它不知道你们聊过什么
翻一遍 3054 三个接入点的请求参数,只有 `text` 和 `args_list`(图片用)。没有 `session_id`,没有 `history`,没有 `context`。
意味着这段对话:
```
用户:昆明天气怎么样
机器人:昆明今天 24℃,多云
用户:那明天呢
```
第二句里的「那明天呢」如果直接丢给接口,`weather` 意图能识别出来,但 `args.area` 大概是抽不到的,因为「昆明」在上一条消息里。
要在多轮场景里用好它,你必须在自己的会话存储里维护最近提到的实体(城市名、快递单号),在调接口之前把它们拼回 `text`。比如把「那明天呢」重写成「昆明明天天气怎么样」再发出去。
这是架构上第一个必须先定的点。
## 三种放置方式
**方式 A:意图层前置。** 3054-2 先判意图和置信度,你的业务层按意图分派,需要平台数据的才调 3054-1,答复由你自己拼。
```
用户消息 → [3054-2 意图分析] → 置信度分档
├─ 低分 → 二次追问(不调 3054-1)
├─ 不支持的意图 → 兜底话术
└─ 高分且支持 → [3054-1 智能对话] → 你的回复层
```
适合:你已经有自己的业务系统,只想把「自然语言 → 结构化参数」这一步外包出去。你拿到 `args` 里的 `area`、`express_nu` 之后,可以塞进自己的查询链路。
**方式 B:执行层直连。** 用户消息直接发 3054-1,拿 `reply_msg.text` 展示。
```
用户消息 → [3054-1 智能对话] → reply_msg.text → 展示
```
适合:答案由平台生成就够用,你不想管业务分支。少一层调用,少 5.5 厘,但拿不到置信度,也分不清「没听懂」和「功能没做」。
**方式 C:流式直连终端。** 3054-3 走 SSE,分块推到前端。
```
用户消息 → [3054-3 流式] → SSE 分块 → 前端逐块渲染
```
适合:前端要边收边渲染,或者后面接了 TTS 需要尽早开口。要注意 3054-3 是透传模式,没有 `showapi_res_body` 外层封装,也没有计费字段。
## 实测延迟预算
做架构决策前先知道每层大概要多久。2026-09-15 的实测数据:
| 环节 | 实测区间 | 样本 |
|------|---------|------|
| 3054-2 意图分析 | 0.70 ~ 1.62 秒 | 9 次调用 |
| 3054-1 智能对话(天气) | 1.62 秒 | 单次 |
| 3054-1 智能对话(快递) | 2.31 秒 | 单次,需要串多家快递数据源 |
| 3054-1 智能对话(新闻) | 1.89 秒 | 单次 |
| 3054-1 失败返回 | 0.65 ~ 1.24 秒 | 2 次 |
| 3054-3 流式(全程) | 1.58 秒 | 单次 |
方式 A 的延迟是两段相加,最坏能到 4 秒左右,对在线客服的体验偏慢。两个可行的缓解手段:把 3054-2 的结果按会话 + 消息内容缓存一段时间;或者只用 3054-2 处理低置信度分支,高分输入直接走 3054-1。
方式 B 的延迟就是单次 3054-1 的时间,1~2.3 秒,可接受。
## 回复层的两个设计决定
**谁负责措辞。** 平台的 `reply_msg.text` 已经写好了话,直接展示最省事,但语气、称呼、是否加表情你控制不了。要品牌一致就别用它的文案,只取 `intent` 和 `result` 自己拼。
**`result` 要不要透给前端。** 天气的 `result` 带 `dayList` 逐日数据,够你画一个卡片;新闻的 `result` 带 20 条 `contentlist`,够你出列表。要自己画 UI 就走"取 `result` 自渲染"的路子,别让前端解析 `reply_msg.text` 里的 Markdown。
## 一份分层实现
```python
import json, time, requests
APP_KEY = "YOUR_APPKEY"
SUPPORTED = {"weather", "query_express", "query_news"}
class Session:
"""接口本身无状态,会话上下文自己在内存里维护。生产环境换成 Redis。"""
def __init__(self):
self.last_entities = {}
def rewrite(self, text):
"""把「那明天呢」补全成「昆明明天天气怎么样」"""
if self.last_entities.get("area") and ("呢" in text or "明天" in text or "后天" in text):
return f"{self.last_entities['area']}{text}", True
return text, False
def absorb(self, args):
for k in ("area", "express_nu"):
if args.get(k):
self.last_entities[k] = args[k]
sessions = {}
def handle(session_id, user_text, timeout=20):
s = sessions.setdefault(session_id, Session())
text, rewritten = s.rewrite(user_text)
t0 = time.time()
# 意图层
r2 = requests.post(f"https://route.showapi.com/3054-2?appKey={APP_KEY}",
data={"text": text}, timeout=timeout)
b2 = r2.json().get("showapi_res_body", {})
if b2.get("ret_code") != 0:
return {"reply": "没听懂,可以换个说法吗", "stage": "intent"}
intent, conf = b2.get("intent"), b2.get("confidence")
s.absorb(b2.get("args") or {})
if intent not in SUPPORTED:
return {"reply": "这个能力还没上线", "intent": intent}
if conf is not None and conf < 80:
return {"reply": "你是想问天气、快递还是新闻?", "intent": intent, "confidence": conf}
# 执行层
r1 = requests.post(f"https://route.showapi.com/3054-1?appKey={APP_KEY}",
data={"text": text}, timeout=timeout)
d1 = r1.json()
b1 = d1.get("showapi_res_body", {})
if b1.get("ret_code") != 0:
return {"reply": "查询失败,稍后再试", "reason": b1.get("ret_msg")}
# 回复层
return {
"reply": b1.get("reply_msg", {}).get("text", ""),
"intent": intent,
"confidence": conf,
"entities": s.last_entities,
"rewritten": rewritten,
"elapsed_s": round(time.time() - t0, 2),
"fee": d1.get("showapi_fee_num"),
}
print(handle("u1", "昆明天气怎么样"))
print(handle("u1", "那明天呢"))
```
`absorb` 那一段是关键。实测 `intent.args` 里能直接抽到 `area` 和 `express_nu`,把它们存进会话,下一句才补得回来。
## FAQ
**Q1:易源合一支持多轮对话吗?**
不支持。实测请求参数只有 `text` 和 `args_list`,没有会话或上下文参数,每次调用都是独立的单句识别。多轮上下文要在你自己的会话存储里维护。
**Q2:3054-1 和 3054-2 该选哪个做入口?**
如果只需要意图标签,用 3054-2。如果需要平台整理好的答复文案和原始数据,用 3054-1。两者可以组合,代价是延迟和费用叠加。
**Q3:并发上有什么限制?**
接口的并发量标注为 10 次/秒。两段式架构会把请求数翻倍,如果你的入口峰值接近这个量级,考虑把 3054-2 的结果做短期缓存。
**Q4:流式接入点能不能直接给前端用?**
技术上可以,3054-3 返回的就是 SSE 格式的文本流。但它是透传模式,没有统一的计费字段,也没有 `showapi_res_body` 封装,前端拿到的 `data` 是嵌套的 JSON 字符串,需要再解析一层。
**Q5:答复文案能改吗?**
`reply_msg.text` 是平台生成的,改不了。要控制文案就只用 `intent` 和 `result` 自己拼回复。
## 下一步阅读
- [易源合一 3054-2 与 3054-1 的搭配方式:先判意图,再决定要不要发起对话](https://www.showapi.com/guides/united-api-intent-precheck-3054)
- [易源合一流式接入点 3054-3:SSE 分块解析与选型取舍](https://www.showapi.com/guides/united-api-streaming-3054)
- [易源合一接进客服机器人:一次接入拿到天气、快递、新闻三类答复](https://www.showapi.com/guides/united-api-chatbot-skill-3054)
- **本系列共 12 篇**:查看[易源合一指南总目录](https://www.showapi.com/guides/united-api-guides-3054)