我们要构建什么

假设我们要构建一个"AI旅行助手",用户可以:

  • 查询航班信息(出发地、目的地、日期)
  • 查询酒店信息(城市、日期、预算)
  • 查询天气(城市、日期)
  • 预订机票和酒店(需要用户确认)

我们将通过这个案例,展示Function Calling系统的完整设计和实现过程。

第一步:函数设计

这是最关键的一步。函数设计的好坏,直接决定了Function Calling系统的成败。每个函数需要包含三个要素:

清晰的名称:模型通过函数名来理解函数的作用。名称应该简洁、明确、遵循动词+名词的命名规范。如search_flights、search_hotels、get_weather、book_flight。

详细的描述:描述是这个函数的设计文档。它应该包含:函数做什么、什么情况下应该调用、返回什么信息。一个好的描述示例:

search_flights: 搜索可用的航班。当用户想查询航班信息时调用此函数。
参数:
- origin: 出发城市,支持中文城市名和IATA机场代码
- destination: 目的地城市,支持中文城市名和IATA机场代码
- date: 出发日期,格式为YYYY-MM-DD
返回:航班列表,每个航班包含航班号、出发时间、到达时间、价格、剩余座位数

合理的参数设计:参数应该包含必需参数和可选参数。必需参数是函数执行的最小信息集,可选参数用于过滤和排序。参数类型应该明确(string、integer、boolean、enum等)。

第二步:对话流程设计

我们的旅行助手需要处理以下对话流程:

  1. 用户表达需求(“我想下周五去成都”)
  2. 模型识别到需要调用search_flights函数
  3. 模型提取参数:origin需要询问(用户没提供出发城市),destination=成都,date=下周五的日期
  4. 模型生成回复询问出发城市
  5. 用户回答"上海"
  6. 模型调用search_flights(origin=“上海”, destination=“成都”, date=“2026-07-17”)
  7. 系统执行函数调用,返回航班列表
  8. 模型将航班列表整理成友好的回复展示给用户

这个流程中,第4步是关键的——模型需要识别出参数不完整,并且主动询问缺失的信息。这是Function Calling系统设计中最容易被忽视但最重要的环节。

第三步:错误处理设计

我们的系统需要处理以下错误场景:

函数调用失败:后端API返回错误。此时应该将错误信息反馈给模型,让模型决定是重试还是告知用户。

参数不完整:模型应该能够识别出参数缺失,并询问用户。

参数不合法:用户说了"下个月32号",模型应该能识别出这是一个无效日期。

超过预算:用户说"预算200元",但搜索结果都是500元以上。模型应该告知用户实际情况,并询问是否调整预算。

第四步:安全设计

对于book_flight和book_hotel这类写入操作,我们的设计原则是:

  • 在调用这些函数之前,必须向用户确认关键信息(航班号、时间、价格)
  • 函数调用需要携带用户的授权token,后端验证token的有效性
  • 所有预订操作记录到审计日志

第五步:对话管理

多轮对话中,模型需要记住之前获取的信息。比如:

  • 用户先查了航班,然后说"帮我看看那边的酒店"
  • 模型需要知道"那边"指的是目的地城市

在系统设计中,我们需要在对话历史中保留关键信息,确保模型在后续对话中能够正确引用。

实战心得

经过这个案例的实践,我们总结了三条最重要的经验:

  1. 函数描述比你想的更重要。花时间写清楚函数描述,比花时间调模型参数更有效。

  2. 错误处理不是可选项。用户不会按照你的预期路径使用系统,错误处理的设计决定了系统的鲁棒性。

  3. 安全是设计出来的。Function Calling系统的安全不能靠"事后加防护",必须在系统设计之初就纳入考虑。

如果你准备构建自己的Function Calling系统,希望这个案例能给你提供一个可参考的框架。