北京时间:2026年4月10日

一、基础信息配置
文章标题:2026年AI助手订酒店实战:从原理到代码示例

目标读者:技术入门/进阶学习者、在校学生、面试备考者、相关技术栈开发工程师
文章定位:技术科普 + 原理讲解 + 代码示例 + 面试要点,兼顾易懂性与实用性
写作风格:条理清晰、由浅入深、语言通俗、重点突出,少晦涩理论,多对比与示例
核心目标:让读者理解概念、理清逻辑、看懂示例、记住考点,建立完整知识链路
二、整体结构写作
开篇引入
在人工智能与生活服务深度融合的2026年,AI助手订酒店已从概念演示走向高频刚需应用。这项能力是构建智能体(Agent)工作流的核心高频考点,也是区分“API调用者”与“AI应用工程师”的关键分水岭。
许多学习者常陷入以下困境:会用Coze、Dify搭建简单对话流,但一旦涉及函数调用(Function Calling) 与提示词工程(Prompt Engineering) 的协作逻辑便混淆不清;能跑通Demo,却说不清AI如何从“我想订房”到真正完成预订的完整链路;面试时被问到“如何保证AI不胡乱捏造酒店ID”更是无从答起。
本文将围绕AI助手订酒店这一具体场景,由浅入深拆解其背后的核心概念、代码实现、底层原理及面试考点。全文涵盖:痛点分析、核心概念(Function Calling)、关联概念(Prompt Engineering)、关系对比、可运行代码示例、底层原理及高频面试题,助你建立完整的知识链路。
痛点切入:为什么需要AI主动“调用函数”?
传统的酒店预订机器人通常采用意图识别 + 规则槽位填充。例如用户说“订一间今晚的希尔顿”,代码流程如下:
传统意图识别伪代码 if "订" in user_input and "酒店" in user_input: intent = "book_hotel" slots = {"hotel_brand": extract_entity(user_input, ["希尔顿", "万豪"]), "checkin_date": extract_date(user_input)} if slots["hotel_brand"] is None: return ask_for_hotel_brand() ... 继续询问其他缺失信息
其缺点显而易见:
高耦合与硬编码:每增加一个新功能(如“订机票”),就要新增一套意图和槽位规则。
扩展性差:无法处理用户复杂的混合指令,如“订希尔顿,但要万豪的价格,且必须能免费取消”。
维护困难:当实体词(酒店品牌、房型)成百上千时,规则引擎变得臃肿不堪。
交互体验僵化:完全按照预设流程“一问一答”,无法像真人一样灵活确认或推荐。
为了解决上述问题,大语言模型(Large Language Model, LLM) 的函数调用能力应运而生。它让AI不再是只会“聊天”的玩具,而是能主动理解需求、决策并调用外部工具的智能助手。
核心概念讲解:函数调用
标准定义:函数调用(Function Calling),在部分平台也称为工具使用(Tool Use),是指大语言模型在生成回复时,根据用户输入和开发者提供的函数签名(Function Signature),自主判断是否需要、以及以何种参数去调用一个外部函数的能力。
拆解关键词:
函数签名:描述函数叫什么、做什么、需要哪些参数(类型、是否必填)。例如:
search_hotel(city: str, date: str, brand: str = None)。自主判断:模型自己决定“现在该不该查酒店”,而非开发者预先写死
if逻辑。参数生成:模型从对话中抽取关键信息,生成为符合函数要求的JSON参数。
生活化类比:
想象你去一家高档餐厅,对AI服务员说:“我有点饿,想吃辣一点的菜,预算100左右。”
传统方式:服务员只会机械地问:“您是要点麻婆豆腐还是水煮肉片?”(意图识别 + 槽位询问)
函数调用方式:服务员立刻理解你的意图,内部自动执行一个
query_dishes(spicy=True, price_max=100)函数,然后拿着结果回来对你说:“推荐您试试水煮牛肉和辣子鸡,都在预算内。”(AI决策 + 自主调用)
作用与价值:
连接LLM与外部世界:让AI能查询实时信息(酒店房态)、执行操作(下订单)。
减少幻觉:强迫模型从函数返回的真实数据中提取信息回复,而非自己编造。
实现复杂工作流:一个对话中可连续多次调用不同函数(查酒店 → 查价格 → 预订 → 发通知)。
关联概念讲解:提示词工程
标准定义:提示词工程(Prompt Engineering) 是指通过设计、优化输入给大语言模型的指令(Prompt),以引导模型生成更准确、更符合预期的输出的实践方法。
与函数调用的关系:
函数调用是实现“AI做什么”的具体手段。
提示词工程是指导“AI如何做”的设计思想。
对比与差异:
| 维度 | 函数调用 (Function Calling) | 提示词工程 (Prompt Engineering) |
|---|---|---|
| 核心 | 定义工具,让AI选择并调用 | 优化指令,引导AI行为 |
| 输出形式 | 结构化的函数名 + JSON参数 | 自然语言文本 |
| 确定性 | 高,参数格式由开发者严格定义 | 低,易受措辞影响 |
| 适用场景 | 需要精确执行操作、获取数据 | 控制回复风格、角色扮演、格式要求 |
| 技术依赖 | 需要模型经过专门微调支持 | 所有LLM通用 |
简单示例说明运行机制:
假设用户问:“帮我看看上海4月12日还有没有万豪酒店?”
仅用提示词:在Prompt中写“你需要查询酒店,请输出JSON格式:
{"action": "search", "city": "...", "date": "..."}”。模型可能输出格式错误,或直接编造“有房”。用函数调用:开发者向API传入函数定义。模型在内部决策后,一定会输出标准的
search_hotel(city="上海", date="2026-04-12", brand="万豪")调用指令。你的代码执行这个函数,拿到真实房态,再返回给模型。
概念关系与区别总结
逻辑关系:提示词工程是“设计说明书”,函数调用是“执行工具包”。前者指导AI的行为边界与风格,后者赋予AI改变世界的能力。
一句话记忆:提示词工程教AI怎么想,函数调用给AI手脚用。
强化对比:
没有函数调用,提示词再精妙,AI也是“四肢瘫痪的军师”。
没有提示词工程,函数调用可能被滥用(AI每句话都想调用函数),或者参数提取错误百出。
代码/流程示例演示
下面是一个极简但完整的AI助手订酒店核心流程模拟。我们使用伪代码演示大模型API与本地函数的协作。
核心逻辑:用户输入 → 发送至LLM(附带函数定义)→ LLM返回函数调用指令 → 本地执行真实函数 → 将结果再次发送给LLM → LLM生成最终自然语言回复。
1. 模拟一个真实的酒店查询函数 def search_hotel(city: str, date: str, brand: str = None): """真实查询酒店数据库(此处模拟)""" print(f"\n[系统] 正在查询 {city},{date},品牌:{brand or '不限'}") 模拟API返回结果 if brand == "希尔顿": return [{"name": "希尔顿花园酒店", "price": 588, "status": "可预订"}] else: return [{"name": "如家精选", "price": 289, "status": "可预订"}] 2. 定义发送给LLM的函数签名(Tool Definition) tools = [{ "type": "function", "function": { "name": "search_hotel", "description": "根据城市、日期和品牌查询可预订酒店", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名称"}, "date": {"type": "string", "description": "入住日期,格式YYYY-MM-DD"}, "brand": {"type": "string", "description": "酒店品牌,如希尔顿、万豪", "enum": ["希尔顿", "万豪", "如家"]} }, "required": ["city", "date"] } } }] 3. 模拟一次完整的交互(用户 -> LLM -> 本地 -> LLM -> 用户) user_query = "我想下周去上海出差,4月17号到,帮我订个希尔顿附近的酒店,要能预订的。" 第一步:用户输入发给LLM print(f"用户:{user_query}") response = llm_chat_with_tools(user_query, tools) 假设的LLM调用 LLM会返回类似: { "tool_calls": [{ "function": {"name": "search_hotel", "arguments": "{\"city\": \"上海\", \"date\": \"2026-04-17\", \"brand\": \"希尔顿\"}"} }] } 第二步:本地执行函数 if response.has_tool_calls: for tool_call in response.tool_calls: if tool_call.function.name == "search_hotel": args = json.loads(tool_call.function.arguments) search_result = search_hotel(args) 执行真实查询 第三步:将函数结果返回给LLM final_response = llm_chat_with_tools( messages=original_messages + [response] + [{ "role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(search_result) }] ) print(f"AI助手:{final_response.content}") 输出示例:为您查到上海希尔顿花园酒店,4月17日可预订,参考价588元。
关键步骤解释:
定义工具:明确告诉LLM有
search_hotel这个能力。LLM决策:模型理解用户意图后,决定调用该工具,并准确提取参数
city="上海",date="2026-04-17",brand="希尔顿"。本地执行:你的代码接收JSON参数,执行真实查询。
结果回传:将真实数据再给LLM,让它组织成自然的回复。整个过程中,AI没有胡说八道,因为数据来自真实调用。
底层原理 / 技术支撑
AI助手能完成订酒店这类多步操作,底层离不开以下关键技术支撑:
大语言模型的特殊微调(Fine-tuning):普通GPT模型只会续写文本。支持函数调用的模型(如GPT-4o、Claude 3、Gemini 1.5系列)在训练时加入了大量“(用户问,工具列表)→ 函数调用指令”的样本,使其学会了何时、为何、如何输出结构化的调用指令。
推理时的强制约束(Constrained Decoding):当模型决定调用函数时,其生成过程并非完全自由。推理引擎会动态施加JSON Schema约束,确保生成的
arguments完全符合函数定义的参数类型、必填项和枚举值。这是避免格式错误的关键。消息角色的扩展:传统对话只有
system、user、assistant。函数调用引入了tool角色,用于承载外部工具返回的结果,形成了用户 → 助手(带工具调用) → 工具 → 助手(最终回复)的标准交互闭环。状态管理与上下文保持:在整个多轮对话和多次函数调用的过程中,客户端(你的代码)负责维护完整的消息历史,每次都将新的
assistant(工具调用请求)和tool(工具结果)追加到上下文中,再发给模型。模型本身无状态,所有逻辑由你的应用层编排。
篇幅所限,本文不深入logit bias、grammar sampling等底层采样细节,后续进阶篇可展开。
高频面试题与参考答案
问题1:请解释大模型函数调用的工作原理。
参考答案:
定义阶段:开发者向模型API提供一个或多个函数定义(包括函数名、描述、参数JSON Schema)。
决策阶段:模型根据用户输入和函数描述,自主判断是否需要调用函数。如需要,则输出一个结构化的
tool_calls对象,其中包含函数名和符合Schema的JSON参数。执行阶段:开发者的应用层代码拦截该输出,解析参数并执行真实的本地函数(如查询数据库、调用第三方API)。
回传阶段:将函数执行结果以
tool角色的消息返回给模型。生成阶段:模型结合原始对话和工具返回的真实数据,生成最终自然语言回复。
踩分点:提及“自主决策”、“结构化输出”、“两阶段调用(请求与回传)”。
问题2:提示词工程和函数调用有什么区别?
参考答案:
本质不同:提示词工程是指导模型如何生成文本的方法论,作用于模型输出风格和内容;函数调用是让模型生成结构化指令的机制,用于连接外部工具。
输出形式不同:提示词工程的输出是自然语言;函数调用的输出是标准的JSON对象。
可靠性不同:函数调用通过约束解码,输出格式几乎100%可靠;提示词工程让模型输出JSON则容易出错。
关系:优秀的提示词工程可以提升函数调用的准确性(如明确指示“不要在未确定参数时调用函数”),但二者是互补而非替代关系。
问题3:在实际开发AI订房功能时,如何防止AI捏造酒店ID?
参考答案:
根本措施:使用函数调用而非让AI直接生成结果。AI只负责生成
search_hotel的查询参数,真实的酒店ID由查询函数从数据库返回。流程隔离:明确划分AI职责(自然语言理解、参数提取)与系统职责(数据查询、业务执行)。AI的回复必须基于
tool角色回传的真实数据。校验机制:在应用层对AI生成的参数进行校验,例如城市名必须在预设列表中,日期必须是合法格式。
提示词约束:在System Prompt中加入“如果你不确定酒店ID,请不要猜测,使用工具查询”等指令,减少模型直接输出的可能性。
结尾总结
核心知识点回顾:
痛点:传统意图识别 + 槽位填充方法耦合高、扩展性差,难以满足复杂交互。
核心概念:函数调用让AI能主动执行外部函数,连接LLM与现实世界。
关联概念:提示词工程负责指导AI的行为风格与决策边界。
关系:函数调用是手段,提示词工程是思想;前者给AI“手脚”,后者教AI“如何思考”。
实现流程:定义工具 → LLM决策并返回参数 → 本地执行 → 结果回传 → 生成回复。
底层原理:依赖模型的特殊微调、约束解码、扩展的消息角色和客户端状态管理。
重点与易错点:
易混淆:不要把函数调用简单理解为“让AI写JSON”,其核心是模型的自主决策能力。
易错:在代码中忘记将
tool角色的消息回传给模型,导致模型“失忆”,无法基于真实数据回复。强调:AI本身不执行任何代码,所有外部动作必须由你的应用程序基于其输出执行。
预告:下一篇我们将深入探讨多步函数调用与并行函数调用,看看AI如何一次对话中自主完成“查询 → 比价 → 预订 → 发邮件”的完整链式操作,并对比ReAct(Reasoning + Acting,推理与行动)模式与函数调用的异同。
本文内容基于截至2026年4月10日的主流大模型技术能力,旨在帮助读者建立清晰、可落地的知识体系。