通过工具调用对接人工交互
核心原理
大模型接口底层存在一个高风险的首词元决策逻辑:模型输出的首个词元,直接决定后续内容是纯自然文本,还是结构化JSON数据。
这个首字符选择会极大影响输出效果:
•
查询东京天气、纯文本回答场景:输出首词一般是普通英文单词,例如 the
•
调用天气查询工具场景:首字符是特殊标记,用来标识JSON对象起始(示例标记:|JSON>)

优化思路
让大模型统一输出JSON格式,再通过字段 intent 区分意图,例如 request_human_input(请求人工介入)、done_for_now(流程暂时结束),而非仅区分查询天气这类标准业务工具。
该方案不一定能直接提升性能,但建议开发者充分实验,自由尝试各类非常规方案,以取得最优效果。
数据结构定义
代码块
Python
from typing import Literal, List
# 人工询问配置项
class Options:
urgency: Literal["low", "medium", "high"] # 紧急程度
format: Literal["free_text", "yes_no", "multiple_choice"] # 回复形式
choices: List[str] # 选择题可选答案
# 对接人工交互的工具结构体
class RequestHumanInput:
intent: "request_human_input"
question: str # 向人工提出的问题
context: str # 提问附带上下文背景
options: Options # 交互配置参数
智能体主循环代码示例
1. 模型输出请求人工指令,暂停流程并持久化状态
代码块
Python
if nextStep.intent == 'request_human_input':
# 将人工询问事件写入会话记录
thread.events.append({
"type": "human_input_requested",
"data": nextStep
})
# 保存完整会话状态,获取会话唯一ID
thread_id = await save_state(thread)
# 推送消息通知人工处理(企业微信/Slack/邮件等渠道)
await notify_human(nextStep, thread_id)
# 跳出主循环,等待人工通过会话ID回复
return
else:
# 处理其他工具分支逻辑
pass
2. 外部Webhook接收人工回复,恢复智能体流程
人工通过Slack、邮件、短信等渠道回复后,系统会触发Webhook接口:
代码块
Python
@app.post('/webhook')
def webhook(req: Request):
# 读取待恢复的会话ID
thread_id = req.body.threadId
# 加载此前保存的完整会话上下文
thread = await load_state(thread_id)
# 将人工回复写入会话事件流
thread.events.append({
"type": "response_from_human",
"data": req.body
})
简化说明:生产环境中不建议在Webhook同步阻塞执行完整流程。
设计复用说明
本段代码融合了前文多条核心理念:
第5条「统一执行状态与业务状态」、第8条「自主掌控控制流」、第3条「自主掌控上下文窗口」、第4条「工具本质是结构化输出」。
自定义XML格式上下文样例(承接第3条规范)
代码块
XML
<slack_message>
发送人: @alex
频道: #deployments
内容: 能否将后端 v1.2.3 部署至生产环境?
历史会话: []
</slack_message>
<request_human_input>
intent: "request_human_input"
question: "确认是否将 v1.2.3 版本部署到生产环境?"
context: "本次为生产环境发布,会影响线上真实用户。"
options: {
urgency: "high"
format: "yes_no"
}
</request_human_input>
该方案核心优势
指令清晰可控
独立的人工交互工具类型,让模型可以精准、细致地定义询问需求。
支持内外双循环流程
突破传统ChatGPT单向「人发起、AI响应」的对话模式;支持反向流程:由定时任务/事件触发智能体,再主动发起人工确认(AI→人)。
多人协同交互
通过标准化事件记录,轻松追踪、协调多位工作人员的输入与反馈。
兼容多智能体联动
同一套抽象结构可直接扩展,实现「智能体向另一智能体发起请求、接收应答」的跨Agent协作。