惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Troy Hunt's Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Schneier on Security
Schneier on Security
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Help Net Security
Help Net Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Palo Alto Networks Blog
P
Privacy International News Feed
AWS News Blog
AWS News Blog
Forbes - Security
Forbes - Security
N
News and Events Feed by Topic
L
LINUX DO - 最新话题
A
Arctic Wolf
Hacker News: Ask HN
Hacker News: Ask HN
P
Proofpoint News Feed
N
News and Events Feed by Topic
S
Security @ Cisco Blogs
Cyberwarzone
Cyberwarzone
Google Online Security Blog
Google Online Security Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
PCI Perspectives
PCI Perspectives
Know Your Adversary
Know Your Adversary
The Hacker News
The Hacker News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Tenable Blog
S
Security Affairs
P
Privacy & Cybersecurity Law Blog
W
WeLiveSecurity
Jina AI
Jina AI
The GitHub Blog
The GitHub Blog
S
Securelist
AI
AI
Latest news
Latest news
T
The Blog of Author Tim Ferriss
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
Cybersecurity and Infrastructure Security Agency CISA
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
G
GRAHAM CLULEY
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
V
Visual Studio Blog
L
LangChain Blog

人人都是产品经理

为什么你的产品找不到差异化?90%的失败都卡在第一步上(下) – 人人都是产品经理, 3年从30万到1300万用户、获2200万美元融资,这个AI教育产品用“抽卡”破解了获客难题 – 人人都是产品经理, 园区招商系统怎么做才能真正帮到去化?我加了这一个功能,推广链接转发400次阅读过万 – 人人都是产品经理, AI大事件:OpenAI发完网络安全模型又搞药物研发,小鹏汽车要抓”DeepSeek时刻” – 人人都是产品经理, 电商不是卖货,是一场更残酷的产品经理实战 – 人人都是产品经理, 没想到,活动营销又回来了! – 人人都是产品经理, 为何All-in海外KOC:一场关于AI时代窗口期的豪赌 – 人人都是产品经理, 重新理解企业的内部协作 – 人人都是产品经理, 苹果的 AI 战略到底是什么? – 人人都是产品经理, 医疗智能体·第2讲——合规护城河:等保、PIPL与HIPAA的架构实战 – 人人都是产品经理, 向量知识库五步法:从“答非所问”到“精准回复” – 人人都是产品经理, 鸿蒙PC三方库构建总指挥HPKBUILD(sha)库为例 – 人人都是产品经理, 何时该用LLM?AI产品经理的LLM设计指南 – 人人都是产品经理, 医疗信息领域的需求方、决策方、准入方以及关注点(二) – 人人都是产品经理, 即梦涨价:一场被误读的「傲慢」 – 人人都是产品经理, 面试AI PM必答题:Hermes和OpenClaw的区别,如何讲清楚业务价值 – 人人都是产品经理, AI的下一张船票:世界模型——AI产品经理必须理解的技术拐点 – 人人都是产品经理, 小红书做GEO,怎么让AI信你?记住这 3 个重要信息 – 人人都是产品经理, 5 家印度 AI 初创公司,看看印度 AI 再做什么 – 人人都是产品经理, AI项目跨团队协作:产品技术业务如何不打架 – 人人都是产品经理, Agentic Workflow(智能体工作流):让AI从”答案生成器”变成”数字员工” – 人人都是产品经理, lycium_plusplus 项目全景解读:OpenHarmony 三方库构建的“大管家” – 人人都是产品经理, 从爆单救火到前置履约:两套预采策略,把生鲜大促履约效率拉满 – 人人都是产品经理, 什么时候该补货?我用一轮数据做了一个决定 – 人人都是产品经理, 从“机械兜底”到“动态分流”:AI客服重复进线治理的4大底层逻辑 – 人人都是产品经理, 抖音拼效率,红书拼洞察 – 人人都是产品经理, 全民狂欢与退潮——为什么龙虾这波热潮冷却得如此之快? – 人人都是产品经理, Stripe押注!MPP重塑全球支付 – 人人都是产品经理, 小红书GEO:AI引用你的内容,不是因为你对,而是因为你看起来可信 – 人人都是产品经理, 前百度副总裁押注办公Agent,日韩付费爆发,Manus迎来强劲对手 – 人人都是产品经理, 企事业单位数字化的业务供需本质 – 人人都是产品经理, 医疗智能体·第1讲——医疗信息化重构:从“辅助软件”到“自主智能体”的范式转移 – 人人都是产品经理, 粉丝量就是空气!!! – 人人都是产品经理, 用户说“薯片碎了”,机器回“要买吗?”:意图识别的翻车与破局 – 人人都是产品经理, RAG召回准确率从75到90 我做对了这三件事 – 人人都是产品经理, AI大事件:Anthropic改收费、OpenAI发安全版、手术机器人纳入医保、阿里发布”秒悟” – 人人都是产品经理, Chrome 推出 Skills 新功能,Agent 重塑上网方式 – 人人都是产品经理, GitHub前创始人拿了a16z的1700万美元,做Agent时代的Git – 人人都是产品经理 拷贝或克隆其他 Flutter OH 项目到本地后无法运行 – 人人都是产品经理, 优惠券设计:优惠券创建 – 人人都是产品经理, 不用死磕文档!AI 助手 1 小时搞定飞书 CLI 安装 + 配置 + 知识库 – 人人都是产品经理, 用小龙虾做竞品分析报告:从2天到20分钟,我是怎么做到的 – 人人都是产品经理 用小龙虾做市场分析报告:搞懂这3个公式,市场规模不再靠猜 – 人人都是产品经理, 你早就在做 Harness 工程,只是不知道它叫这个名字 – 人人都是产品经理, Think Long就够?你可能想多了! – 人人都是产品经理, 货代SRM实战:供应商准入怎么做,才能让资源池不是通讯录而是可交付网络? – 人人都是产品经理, 如何做好用户调研?详解基本技巧 – 人人都是产品经理, 木鸟、途家、美团对打,平台春天行动开“卷” – 人人都是产品经理, 入职才发现公司不靠谱?小红书从业者求职避坑指南 – 人人都是产品经理, 美国 AI 三巨头联手封堵,中国 AI 突围之路在何方 – 人人都是产品经理, 小红书,放在需求对面的镜子 – 人人都是产品经理, AI 会带来大规模失业吗? – 人人都是产品经理, 从出单到补货前,我第一次犹豫:该不该放大? – 人人都是产品经理, Flutter 三方库鸿蒙化适配:5 种高效检查方式,快速判断是否需要适配 – 人人都是产品经理, 从做产品进阶拿结果:医美机构产品经理转岗科室运营经理 – 人人都是产品经理, 阿里HappyHorse,一场关于“Token经济”的阳谋 – 人人都是产品经理, To B AI:客户留存落地的观察与思考 – 人人都是产品经理, AI产品的“生命线”——数据采集、标注、清洗的产品化设计 – 人人都是产品经理, 谈谈AI Agent(二):当“孩子”能自己“体验世界”时,你该学什么? – 人人都是产品经理, UI/UX设计师的3层能力进阶,前两层让你活下来,第三层…才是真正的分水岭 – 人人都是产品经理, 2分钟 → 30秒,效率提升75%:B端产品经理如何用「规则枷锁」驯服AI幻觉? – 人人都是产品经理, 还没来得及学OpenClaw,来了个更猛的:Hermes Agent – 人人都是产品经理, AI日报:宇树机器人跑出10m/s刷新世界纪录 – 人人都是产品经理, 一文说透基金互金如何用情绪价值引导用户决策做转化 – 人人都是产品经理, 当浏览器开始替你”看”网页:AI 浏览器正在亲手拆掉它脚下的那张网 – 人人都是产品经理, 0代码,一天时间我Vibe Coding了个网站 – 人人都是产品经理, Hermes 和 OpenClaw 之争,Agent 的能力应该“装上去”还是“长出来”? – 人人都是产品经理 视频生成的“桌子”,字节Seedance 2掀完,阿里快乐马掀 – 人人都是产品经理, 从听不懂到完全信任:我的 Codex 深度产品体验 – 人人都是产品经理, 当虚拟偶像有了北京户口,与真人偶像还有什么区别? – 人人都是产品经理, 会说,远远比会做更重要 —— 对 SBTI 爆火现象的五层观察 – 人人都是产品经理, AI产品经理必看:当“搭环境”比“选模型”更重要,你的认知还在2024年吗? – 人人都是产品经理, 2026年AI产品商业化核心逻辑:从功能demo到规模化营收的3个必破卡点 – 人人都是产品经理, 京东围绕供应链,卷起裤腿下场的那些事儿 – 人人都是产品经理, SBTI一夜刷屏:它赢在了“太会说人话” – 人人都是产品经理, 折扣零售的真相:不是便宜,而是价值感! – 人人都是产品经理, 和甲方吵了一架,最后加钱做了——我学到的ToB产品经理生存法则 – 人人都是产品经理, 和几位小红书操盘手聊了8小时,干货全在这 – 人人都是产品经理, 智谱GLM-5.1登场,开源模型首超Opus4.6!!! – 人人都是产品经理 Anthropic收入凭什么反超OpenAI,终于有人把这事说清楚了 – 人人都是产品经理, 史上最有故事感的技术报告——Claude最强模型Mythos 7个极其精彩的细节 – 人人都是产品经理, 模型不是壁垒,Harness 也不是 – 人人都是产品经理, 抖音本地生活业务思考21 – 人人都是产品经理, Superpowers:145k Star的AI编码框架,到底是什么来头? Superpowers:145k Star的AI编码框架,到底是什么来头? – 人人都是产品经理, OpenAI 的路走错了,Anthropic Harness 解法启示:模型需要实践专科生 – 人人都是产品经理, 画原型图的前一步:设计站点地图 – 人人都是产品经理, 给 DeepSeek 的最后一封催更信 – 人人都是产品经理, 手把手教你用 Claude Code 搭建 AI 营销团队:5 个 Agent、12 项技能,独立完成研究、写作、设计全流程 – 人人都是产品经理, 你以为大模型在学语言?不,它在重新发明语言学 – 人人都是产品经理 所谓Skill,不过是AI时代的工业垃圾 – 人人都是产品经理, 聊一聊内容传播的几个方法 – 人人都是产品经理, 当平台开始吃掉生态:从 OpenClaw 被封杀,读懂 Anthropic 的这盘棋 – 人人都是产品经理, 你装了 10 个 AI 插件,Obsidian 还是一个文件夹 – 人人都是产品经理 关于AI智能体架构演进的系统性思考:从单体试水到多体协同的重构 – 人人都是产品经理, 当“人”变成Skill,我们又该何去何从? – 人人都是产品经理 Mythos 事件:前沿 AI 治理的意外实验 – 人人都是产品经理, 货代CRM:信用与风险管理怎么做,才能把坏账风险拦在放货之前? – 人人都是产品经理, 从HR收集自拍照到员工自助录入——我见证了园区人脸识别从”不可用”到”真好用”的全过程 – 人人都是产品经理 千问闯关AI混沌期:阿里画靶,吴嘉张弓,马云射箭? – 人人都是产品经理,
看完这篇,你也能做 AI 搜索:论「结构化输出」
赛博禅心 · 2024-08-19 · via 人人都是产品经理

随着AI技术的不断进步,结构化输出的应用将越来越广泛,从AI搜索到IoT设备适配,再到复杂的对话系统,结构化输出都扮演着至关重要的角色。了解和掌握结构化输出的使用方法,对于AI行业的从业者来说,是提升产品性能和用户体验的关键。

先说结论:结构化输出,是绝大多数 AI 产品和 Agent 的核心

无论是 AI 搜索、有记忆的 bot,还是各类 agent,都是基于结构化输出搭建的。

在这篇文章里,我讲从多角度讲一下结构化输出的用途、起源和示例。

同时,文章会附带一些代码片段,方便更直观的表现(当然,完全不看关系也没问题)

一、什么是「格式化输出」

如果我问 GPT:介绍一下乔布斯

通常会收到这样的回复:

史蒂夫·乔布斯,1955年2月24日出生,2011年10月5日去世,美国人。他活跃于科技、创新、企业管理和动画领域。乔布斯创立了Apple、NeXT和Pixar公司,推出了Mac、iPod、iPhone等具有划时代意义的产品,重塑了个人电脑、音乐和手机行业,奠定了苹果在全球科技领域的领军地位。作为Pixar的创办人之一,他也在动画领域留下了深远的影响。乔布斯是20世纪末至21世纪初最具影响力的企业家和创新者之一。

而在很多 AI 产品中,我们并非看到一串文字,而是这样的脑图:

其背后,就是结构化输出 – 让 AI 输出 json,而非文本,比如:

{
“name”: “史蒂夫·乔布斯”,
“birth_date”: “1955-02-24”,
“death_date”: “2011-10-05”,
“nationality”: “美国”,
“fields”: [“科技”, “创新”, “企业管理”, “动画”],
“companies_founded”: [“Apple”, “NeXT”, “Pixar”],
“achievements”: [
“创立苹果公司”,
“推出Mac、iPod、iPhone等产品”,
“重塑个人电脑、音乐、手机行业”,
“奠定苹果全球科技领军地位”,
“Pixar创办人之一”
],
“influence”: “20世纪末至21世纪初最具影响力的企业家和创新者之一”
}

二、产品的背后,都是结构化输出

依然拿「介绍一下乔布斯」这个问题举例,在不同 AI 产品中,这个问题的内部输出是不同的。

如果是搜索,它的内部输出可能是这样:

{
“query”: “乔布斯”,
“search_by”: “Google”
}

获得这个结果后,再用谷歌搜索「乔布斯」,并将结果通过 AI 总结,返回给用户。

对于 Rag 工具,其数据库为《硅谷县志》,它的内部输出可能是这样

{
“rag1”: “乔布斯的家庭”,
“rag2”: “乔布斯的成长”,
“rag3”: “乔布斯的产品”,
“rag4”: “乔布斯的成就”,
}

分别对这几个信息进行 rag 后,在把结果汇总,通过 AI 总结,返回给用户。

对于四格漫画,其内部输出可能是这样的:

{
“stories”: [
{
“story”: “乔布斯的家庭”,
“prompt”: “20世纪70年代复古风格,温暖的色调,柔和的线条。在美国加州的一间温馨家庭住宅,窗外阳光明媚,庭院中充满绿植和鲜花。年轻的乔布斯与他的养父母在客厅里,其母亲在织毛衣,父亲在看报纸,乔布斯坐在地上玩着一台老式计算机。画面呈现出和谐温馨的家庭场景,浓厚的亲情氛围中,乔布斯的眼中充满了好奇与探索。”,
“caption”: “家庭的力量塑造了伟大的梦想”},
{
“story”: “乔布斯的成长”,
“prompt”: “1970年代末期的黑白摄影风格,带有强烈的对比效果。在旧金山一所简朴的高中教室,光线从窗外斜射进来,课桌上摆满了书本和笔记。年轻的乔布斯坐在教室后排,注视着老师手中的物理实验,身边的同学们都在认真听课。画面体现了乔布斯对知识的渴望,眼神专注,透出不凡的好奇心和思考的深度。”,
“caption”: “追求知识与个人成长”},
{
“story”: “乔布斯的产品”,
“prompt”: “极简主义风格,采用现代化的色彩搭配,注重设计感。在苹果公司现代化的办公室内,简洁的玻璃桌面上摆放着第一代Macintosh,背景是白色的墙壁和大型苹果标志。乔布斯站在桌前,手指轻触Macintosh,身后几位工程师在讨论。画面重点突出乔布斯与他的产品,展示出科技与设计的完美结合,乔布斯的神态自信且充满远见。”,
“caption”: “通过产品改变世界”},
{
“story”: “乔布斯的成就”,
“prompt”: “超现实主义风格,带有未来感,色彩鲜明且具有冲击力。在庞大的苹果公司总部前,未来风格的天空中悬浮着乔布斯的头像,周围环绕着iPhone、iPad、Mac等产品。乔布斯的巨大肖像与天空中的科技产品融为一体,象征着他对现代科技的深远影响。画面展现了一幅震撼的图景,乔布斯的形象如同神话般屹立在现代科技的顶峰。”,
“caption”: “达到科技的巅峰”
}
]}

然后分别对这几个信息,进行画图,在展示给用户。

三、以「AI 天气预报」为例

现在换个例子:我有一个天气预报 AI,如果用户问到了天气,则进行告知。

实际上,这个 AI 并不是真的用 AI 去实时预测,而是问题,转化成一个请求,去查询「天气预报数据库」,再返回给用户(当然,如果用户的问题和天气无关,则正常回答)。

具体的流程如下:

从程序的角度,执行以下:

1)通过结构化输出,判断该问题和天气有关,并拆解出 location 和 date 两个字段分别是 北京  和 明天

2)向接口请求信息 北京  和 明天 (严谨来说是,Beijing 和 2024-08-16)

3)AI 进行结构化返回:

{
“date”: “2024-08-16”,
“location”: “北京”,
“temperature”:
{
“high”: “32°C”,
“low”: “24°C”
},
“weather”: “雷阵雨,云层厚”,
“humidity”: “77%”,
“UV_index”: “高”,
“advice”: “携带雨具,注意防晒”
}

4)向接口发送类似下面的信息

client.chat.completions.create(
model=”gpt-4o”,
messages=[
{“role”: “system”, “content”: “你是天气预报机器人,今天是 2024-08-16”},
{“role”: “user”, “content”: “””
{“date”: “2024-08-16″,”location”: “北京”,”temperature”: {“high”: “32°C”,”low”: “24°C”},”weather”: “雷阵雨,云层厚”,”humidity”: “77%”,”UV_index”: “高”,”advice”: “携带雨具,注意防晒”}
北京明天的天气怎么样?
“””}
]
)

5)接口返回的结果,会类似:

明天北京的天气预报显示白天的气温将达到最高约32°C,夜间最低温度约为24°C。预计会有雷阵雨,全天云层较厚,湿度较高,达到77%左右。雷阵雨可能会在上午和下午出现,因此出行时建议携带雨具,并注意防晒,因为紫外线指数较高。总的来说,天气闷热,空气湿润,体感温度可能会比实际温度更高

也可以利用「结构化输出」,对设备进行 IoT 适配。

比如,我学过电工(EE),就可以让 Coze 变成一个家庭中控,如:

家里的数据:

封装成 Coze Bot:

四、产业演化史

在 AI 领域,我们通常认为,结构化输出的第一次大规模使用,是源自去年 5 月 OpenAI 的 Plugin 正式上线:AI 可以通过结构化输出,来调用外部工具。

并且,截止到当前,OpenAI 在结构化输出这块,供进行了 4 次迭代,包括 Plugin 方法,Function Calling,Json Mode 和前两天新出的 Structured Outputs。

当然了,你也可以用 markdown 等 prompt 方法来模拟结构化输出,但不在本次的讨论范围。

Plugin 方法

在 2023 年 3 月,当时参与到 plugin 内测的朋友,会看到一份如何让 ChatGPT 调用外部工具的文档,也是结构化输出的雏形。

流程就和上文一样,ChatGPT 在获知用户的请求后,通过结构化输出的方式,生成包括插件选择在内的一个 json,插件在接受到这些参数后开始处理,并给到一个回调。之后这套东西,变成了 GPTs 的 Action。

注意:这套方法并未通过接口的方式发布

Function Calling

在 2023 年 6 月,OpenAI 带来了 0613 年中更新,并发布了 Function Calling,也是现在看来最广泛使用的调用方法,国内模型普遍支持。

下面,我们以一个更直观的例子,来看看 Function Calling 的使用过程。以 用户查询包裹 为例,这个 bot 处理任务的过程中,总计分 2 步:

1)用户向 AI 询问【我的包裹,编号12345,寄了吗?】的时候,其请求额外带上字段 tools,在其中定义要获取的信息 order_id

2)假设获取到的信息是 order_12345 ,通过查询数据库,获得包裹信息 2024-08-01

3)将这个信息,和历史提问合并,再交给大模型,获得最终输出 包裹在 2024-08-01 的时候已经寄出去了

如果用代码的方式,就是:

tools = [
{
“type”: “function”,
“function”: {
“name”: “get_delivery_date”,
“description”: “Get the delivery date for a customer’s order. Call this whenever you need to know the delivery date, for example when a customer asks ‘Where is my package'”,
“parameters”: {
“type”: “object”,
“properties”: {
“order_id”: {
“type”: “string”,
“description”: “The customer’s order ID.”
}
},
“required”: [“order_id”],
“additionalProperties”: False
}
}
}
]

messages = []
messages.append({“role”: “system”, “content”: “You are a helpful customer support assistant. Use the supplied tools to assist the user.”})
messages.append({“role”: “user”, “content”: “Hi, can you tell me the delivery date for my order?”})
messages.append({“role”: “assistant”, “content”: “Hi there! I can help with that. Can you please provide your order ID?”})
messages.append({“role”: “user”, “content”: “i think it is order_12345”})

rsp = client.chat.completions.create(
model=’gpt-4o’,
messages=messages,
tools=tools
)

之后,AI 会返回类似:

ChatCompletion(id=’chatcmpl-9wY3ulTLZswqZLF58L0LQ0sM1EAsG’, choices=[Choice(finish_reason=’tool_calls’, index=0, logprobs=None, message=ChatCompletionMessage(content=None, refusal=None, role=’assistant’, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id=’call_W1KzfgxvkoxjCAGT3Td9oVPk’, function=Function(arguments='{“order_id”:”order_12345″}’, name=’get_delivery_date’), type=’function’)]))], created=1723740986, model=’gpt-4o-2024-05-13′, object=’chat.completion’, service_tier=None, system_fingerprint=’fp_3aa7262c27′, usage=CompletionUsage(completion_tokens=19, prompt_tokens=140, total_tokens=159))

其中 response.choices[0].message.tool_calls[0].function.arguments 的值,就是 {“order_id”:”order_12345″}

假定查询到的结果是 2024-08-01

# Prepare the chat completion call payload
completion_payload = {
“model”: “gpt-4o”,
“messages”: [
{“role”: “system”, “content”: “You are a helpful customer support assistant. Use the supplied tools to assist the user.”},
{“role”: “user”, “content”: “Hi, can you tell me the delivery date for my order?”},
{“role”: “assistant”, “content”: “Hi there! I can help with that. Can you please provide your order ID?”},
{“role”: “user”, “content”: “i think it is order_12345”},
rsp.choices[0].message,
{“role”: “tool”, “content”: “delivery_date:2024-08-01”, “tool_call_id”: rsp.choices[0].message.tool_calls[0].id},
]
}

# Call the OpenAI API’s chat completions endpoint to send the tool call result back to the model
response = client.chat.completions.create(
model=completion_payload[“model”],
messages=completion_payload[“messages”],
)

# Print the response from the API. In this case it will typically contain a message such as “The delivery date for your order #12345 is xyz. Is there anything else I can help you with?”
print(response)

最终,你会得到

ChatCompletion(id=’chatcmpl-9wYV7Yhkimzlpg3ejNkjRjI0GKqyw’, choices=[Choice(finish_reason=’stop’, index=0, logprobs=None, message=ChatCompletionMessage(content=’Your order with ID “order_12345” is scheduled to be delivered on August 1, 2024. If you have any other questions or need further assistance, feel free to ask!’, refusal=None, role=’assistant’, function_call=None, tool_calls=None))], created=1723742673, model=’gpt-4o-2024-05-13′, object=’chat.completion’, service_tier=None, system_fingerprint=’fp_3aa7262c27′, usage=CompletionUsage(completion_tokens=40, prompt_tokens=111, total_tokens=151))

也就是  包裹在 2024-08-01 的时候已经寄出去了

回顾一下

上面完成这个对话的时候,用户给出了一次 prompt: i think it is order_12345,但 AI 实际上是跑了 2 次:

第一次是获取 order id

第二次才是真正是生成内容  包裹在 2024-08-01 的时候已经寄出去了

同时,在第二次的对话中,结尾挂着 第一次的 response 和 数据库查找结果。

在数据库的查询结果中,role 为 tool

还需注意

如果你在某些代码中,看到 Function Calling 的查询信息,不是用 tool,而是用 function,这也没错。

因为 OpenAI 曾经改过 Function Calling 的接口实现:最开始是  function 结构,后面改成了 tool 结构。对于 tool  和 function 这两种写法,目前都行,但后续 OpenAI 将只支持 tool 结构

吐槽:我个人更喜欢 function 结构,更优雅

使用 tool 结构”messages”:

“messages”: [
{“role”: “system”, “content”: “You are a helpful customer support assistant. Use the supplied tools to assist the user.”},
{“role”: “user”, “content”: “Hi, can you tell me the delivery date for my order?”},
{“role”: “assistant”, “content”: “Hi there! I can help with that. Can you please provide your order ID?”},
{“role”: “user”, “content”: “i think it is order_12345”},
rsp.choices[0].message,
{“role”: “tool”, “content”: “delivery_date:2024-08-01”, “tool_call_id”: rsp.choices[0].message.tool_calls[0].id}]

使用 function 结构

“messages”: [
{“role”: “system”, “content”: “You are a helpful customer support assistant. Use the supplied tools to assist the user.”},

{“role”: “user”, “content”: “Hi, can you tell me the delivery date for my order?”},
{“role”: “assistant”, “content”: “Hi there! I can help with that. Can you please provide your order ID?”},
{“role”: “user”, “content”: “i think it is order_12345”},
{“role”: “function”, “content”: “delivery_date:2024-08-01”, “name”: “delevery_record”}]

使用 function 结构

“messages”:[
{“role”: “system”, “content”: “You are a helpful customer support assistant. Use the supplied tools to assist the user.”},
{“role”: “user”, “content”: “Hi, can you tell me the delivery date for my order?”},
{“role”: “assistant”, “content”: “Hi there! I can help with that. Can you please provide your order ID?”},
{“role”: “user”, “content”: “i think it is order_12345”},
{“role”: “function”, “content”: “delivery_date:2024-08-01”, “name”: “delevery_record”}
]

使用 function 结构

“messages”: [
{“role”: “system”, “content”: “You are a helpful customer support assistant. Use the supplied tools to assist the user.”},
{“role”: “user”, “content”: “Hi, can you tell me the delivery date for my order?”},
{“role”: “assistant”, “content”: “Hi there! I can help with that. Can you please provide your order ID?”},
{“role”: “user”, “content”: “i think it is order_12345”},
{“role”: “function”, “content”: “delivery_date:2024-08-01”, “name”: “delevery_record”}]

另外:也可以两种结构都不用

“messages”: [
{“role”: “system”, “content”: “You are a helpful customer support assistant. Use the supplied tools to assist the user.”},
{“role”: “user”, “content”: “Hi, can you tell me the delivery date for my order?”},
{“role”: “assistant”, “content”: “Hi there! I can help with that. Can you please provide your order ID?”},
{“role”: “user”, “content”: “i think it is order_12345. Related record is: delivery_date:2024-08-01”}]

Json Mode

在 2023 年 11 月,OpenAI 在开发者大会上,带来了 Json Mode 更新。

仔细看上面的 Function Calling,其参数是通过 string 给到的,不够稳定。Json Mode 便是为了解决这一问题:直接输出 Json。

注意:这种方法仍然不够稳定,并已被 Structured Outputs 取代

调用的时候,要求:

  • prompt 里出现 json 这个单词
  • response_format 设置为 “type”: “json_object”

比如

completion_payload = {
‘model’: ‘gpt-3.5-turbo’,
‘messages’: [{‘role’: ‘user’, ‘content’: ‘告诉我四大名著分别是什么,以及他们的作者是谁,按这个 json 格式: {{‘书名’:’xxx’,’作者’:’xxx’}…}’}],
‘response_format’: {‘type’: ‘json_object’}
}

# Call the OpenAI API’s chat completions endpoint to send the tool call result back to the model
response = client.chat.completions.create(
model=completion_payload[“model”],
messages=completion_payload[“messages”],
)

得到 resoponse 为Chat

Completion(id=’chatcmpl-9wZ5DHWicaarxccmTBGi8MfJsa6AQ’, choices=[Choice(finish_reason=’stop’, index=0, logprobs=None, message=ChatCompletionMessage(content=”{n    {‘书名’: ‘西游记’, ‘作者’: ‘吴承恩’},n    {‘书名’: ‘红楼梦’, ‘作者’: ‘曹雪芹’},n    {‘书名’: ‘水浒传’, ‘作者’: ‘施耐庵’},n    {‘书名’: ‘三国演义’, ‘作者’: ‘罗贯中’}n}”, refusal=None, role=’assistant’, function_call=None, tool_calls=None))], created=1723744911, model=’gpt-3.5-turbo-0125′, object=’chat.completion’, service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=92, prompt_tokens=57, total_tokens=149))

其中,通过 response.choices[0].message.content 可去到 json 信息,如需进行后续处理,依然沿用 function calling 中的方法

Structured Outputs

较之 Function Calling 和 Json Mode,Structured OutPuts 明显好用了很多,当前支持以下模型:gpt-4o-mini, gpt-4o-2024-08-06,当然,也包括之后的模型。

简单调试测试一下

刚才的四大名著的例子,代码这么写

from pydantic import BaseModel

class theBook(BaseModel):
name: str
writer: str

class theFour(BaseModel):
steps: list[theBook]

completion = client.beta.chat.completions.parse(
model=”gpt-4o-2024-08-06″,
messages=[
{“role”: “system”, “content”: “Extract the event information.”},
{“role”: “user”, “content”: “告诉我四大名著分别是什么,以及他们的作者是谁”},
],
response_format = theFour,
)

response = completion.choices[0].message.parsed

得到的结果是

theFour
(
steps=[
theBook(name=’《红楼梦》’, writer=’曹雪芹’),
theBook(name=’《西游记》’, writer=’吴承恩’),
theBook(name=’《三国演义》’, writer=’罗贯中’),
theBook(name=’《水浒传》’, writer=’施耐庵’)])

非常好用!

通过这种方法,还可以完成单次对话的 CoT,比如:

from pydantic import BaseModel

class Step(BaseModel):
explanation: str
output: str

class MathReasoning(BaseModel):
steps: list[Step]
final_answer: str

completion = client.beta.chat.completions.parse(
model=”gpt-4o-2024-08-06″,
messages=[
{“role”: “system”, “content”: “You are a helpful math tutor. Guide the user through the solution step by step.”},
{“role”: “user”, “content”: “how can I solve 8x + 7 = -23”}    ],    response_format=MathReasoning,)math_reasoning = completion.choices[0].message.parsed

得到结果

{
“steps”: [
{
“explanation”: “Start with the equation 8x + 7 = -23.”,      “output”: “8x + 7 = -23”
},
{
“explanation”: “Subtract 7 from both sides to isolate the term with the variable.”,      “output”: “8x = -23 – 7”
},
{
“explanation”: “Simplify the right side of the equation.”,      “output”: “8x = -30”

},

{

“explanation”: “Divide both sides by 8 to solve for x.”,      “output”: “x = -30 / 8”

},

{

“explanation”: “Simplify the fraction.”,      “output”: “x = -15 / 4”

}  ],

“final_answer”: “x = -15 / 4”

}

结语

以上差不多就是就是关于「结构化输出」的大致内容。以及…

最近我在写一个「AI 行业」的知识库,会有很多类似本篇的信息,完全面向从业者的。

等搞得差不多了,请大家来看~拜了个拜~

本文由人人都是产品经理作者【赛博禅心】,微信公众号:【赛博禅心】,原创/授权 发布于人人都是产品经理,未经许可,禁止转载。

题图来自Unsplash,基于 CC0 协议。