图片来源网络,侵权联系删。

文章目录
-
- [1. 引言](#1. 引言)
- [2. Web 开发与 AI Agent 的天然衔接点](#2. Web 开发与 AI Agent 的天然衔接点)
- [3. Function Calling 提示词优化的核心原理](#3. Function Calling 提示词优化的核心原理)
-
- [3.1 Function Calling = 接口契约驱动](#3.1 Function Calling = 接口契约驱动)
- [3.2 提示词模板 = 组件 Props](#3.2 提示词模板 = 组件 Props)
- [3.3 上下文管理 = 状态管理](#3.3 上下文管理 = 状态管理)
- [4. 用 Java + Vue 构建一个 Function Calling Agent](#4. 用 Java + Vue 构建一个 Function Calling Agent)
-
- [4.1 后端:Spring Boot 定义 Function 并集成 LLM](#4.1 后端:Spring Boot 定义 Function 并集成 LLM)
- [4.2 前端:Vue 展示 Agent 执行过程](#4.2 前端:Vue 展示 Agent 执行过程)
- [4.3 端到端流程图(Mermaid)](#4.3 端到端流程图(Mermaid))
- [5. 常见问题与 Web 开发者专属解决方案](#5. 常见问题与 Web 开发者专属解决方案)
-
- [问题1:LLM 不调用函数,直接编造答案](#问题1:LLM 不调用函数,直接编造答案)
- 问题2:函数参数格式错误(如日期、枚举)
- [问题3:高并发下 LLM 成本飙升](#问题3:高并发下 LLM 成本飙升)
- [6. Web 开发者的 AI 转型路径](#6. Web 开发者的 AI 转型路径)
1. 引言

在传统 Web 开发中,我们常遇到这样的场景:产品经理说"查一下用户订单",但没说明是哪个用户、什么时间范围。前端按模糊理解调用接口,后端返回空数据,双方互相甩锅------最终发现是需求未转化为清晰的接口契约。
如今,当我们转向 AI 应用开发,类似问题以新形式重现:用户问"北京明天天气怎么样?",如果只给 LLM 一句提示词,它可能凭记忆瞎编一个"晴,25℃"。这不是模型蠢,而是我们没给它"查天气"的工具和调用规范。
💡 关键洞察:Function Calling 就是 Web 开发中的"接口定义"------你告诉 LLM:"你可以调用这些函数,这是它们的参数和用途",模型就不再靠猜,而是像前端调用 REST API 一样精准执行。
本文将手把手教你,如何用 Web 开发者的思维,通过 Function Calling 优化提示词,构建可控、可靠、可扩展的 AI Agent 应用。
2. Web 开发与 AI Agent 的天然衔接点

Web 开发者转型 AI Agent 开发,其实站在巨人的肩膀上。以下是核心衔接点:
| Web 开发概念 | AI Agent 对应概念 | 说明 |
|---|---|---|
| RESTful API | Function | 每个后端接口可注册为 LLM 可调用的函数 |
| OpenAPI / Swagger | Function Schema | JSON Schema 定义函数输入输出,LLM 依此生成调用 |
| JWT / RBAC | Function 可见性控制 | 某些函数仅对管理员开放,类似权限系统 |
| 前端 Loading 状态 | Agent 执行轨迹可视化 | 展示"正在调用 getWeather..."提升用户体验 |
举个例子:你已有 /api/weather?city=北京 这个接口。只需将其包装成 Function Schema,LLM 就能自动调用它,无需重写业务逻辑。
3. Function Calling 提示词优化的核心原理

3.1 Function Calling = 接口契约驱动
传统提示词:
text
用户:北京天气如何?
模型:北京今天晴,气温20℃。(可能过时或错误)
使用 Function Calling:
text
你是一个天气助手。你可以调用以下函数:
- getWeather(city: string): 获取指定城市当前天气
用户:北京天气如何?
模型:{"function_call": {"name": "getWeather", "arguments": {"city": "北京"}}}
→ 后端收到后,执行 getWeather("北京"),将真实结果返回给模型,再由模型组织语言回复。
这就像前端不会自己计算订单总价,而是调用 /api/calculateTotal ------职责分离,结果可靠。
3.2 提示词模板 = 组件 Props
我们将提示词拆解为:
- System Prompt(固定):定义角色和可用函数(类似组件 defaultProps)
- User Message(动态):用户输入(类似传入的 props)
java
// Java 伪代码:构建 messages
List<Message> messages = new ArrayList<>();
messages.add(new SystemMessage("你是天气助手,只能通过 getWeather 获取信息"));
messages.add(new UserMessage(userInput));
3.3 上下文管理 = 状态管理
对话历史会消耗 token。Web 开发者熟悉 Vuex/Pinia 的状态裁剪策略,同样可用于 Agent:
- 保留最近 N 轮对话
- 合并无关消息(如"好的""谢谢")
- 关键函数调用结果必须保留
4. 用 Java + Vue 构建一个 Function Calling Agent

4.1 后端:Spring Boot 定义 Function 并集成 LLM
Step 1:定义 WeatherService
java
@Service
public class WeatherService {
public String getWeather(String city) {
// 模拟调用第三方API
return city + "当前晴,气温22℃";
}
}
Step 2:构建 Function Schema(符合 OpenAI 格式)
java
public class FunctionDefinition {
private String name;
private String description;
private JsonNode parameters; // JSON Schema
}
Step 3:调用 OpenAI API(使用 OkHttp 或 WebClient)
java
// 构建请求体
ObjectNode body = objectMapper.createObjectNode();
body.putArray("messages").add(...);
body.putArray("functions").add(functionSchema);
// 调用 POST https://api.openai.com/v1/chat/completions
Response response = client.newCall(request).execute();
Step 4:处理 function_call 响应
java
if (response.has("function_call")) {
String functionName = response.get("function_call").get("name").asText();
JsonNode args = objectMapper.readTree(response.get("function_call").get("arguments").asText());
if ("getWeather".equals(functionName)) {
String result = weatherService.getWeather(args.get("city").asText());
// 将 result 作为 function response 再次调用 LLM
}
}
4.2 前端:Vue 展示 Agent 执行过程
vue
<template>
<div v-for="(msg, index) in conversation" :key="index">
<div v-if="msg.role === 'user'">👤 {{ msg.content }}</div>
<div v-else-if="msg.tool_calls">
🤖 正在执行:
<div v-for="tool in msg.tool_calls" :key="tool.id">
→ {{ tool.function.name }}({{ tool.function.arguments }})
</div>
</div>
<div v-else>🤖 {{ msg.content }}</div>
</div>
</template>
4.3 端到端流程图(Mermaid)
WeatherAPI LLM Backend Frontend User WeatherAPI LLM Backend Frontend User 输入"北京天气?" POST /chat {message: "北京天气?"} 发送 messages + functions 返回 function_call: getWeather(city="北京") 调用 getWeather("北京") 返回真实天气 发送 function response 返回自然语言回复 返回最终消息 显示"北京当前晴,22℃"
5. 常见问题与 Web 开发者专属解决方案

问题1:LLM 不调用函数,直接编造答案
原因 :system prompt 不够强硬,或 temperature 过高。
解决:
- System prompt 明确:"你必须通过调用函数获取信息,禁止猜测。"
- 设置
temperature=0,关闭随机性。
问题2:函数参数格式错误(如日期、枚举)
原因 :Schema 定义不严。
解决:
json
{
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date" // 明确格式
},
"type": {
"type": "string",
"enum": ["daily", "hourly"] // 限制取值
}
}
}
}
后端仍需做二次校验,如同 Web 接口的 DTO 验证。
问题3:高并发下 LLM 成本飙升
解决:
- 缓存函数结果 :用 Redis 缓存
getWeather("北京")结果,5分钟内相同请求直接返回。 - 降级策略:非核心功能(如闲聊)不启用 Function Calling。
6. Web 开发者的 AI 转型路径

Function Calling 让 Web 开发者能复用现有工程能力快速构建 AI Agent:
- 你懂 API 设计 → 你能设计高质量 Function Schema
- 你懂状态管理 → 你能管理 Agent 对话上下文
- 你懂前后端协作 → 你能打造流畅的 Agent 交互体验
学习路径建议:
- 入门:将现有 REST API 包装为 Function,实现单轮问答
- 进阶:支持多函数调用、多轮对话(如"先查天气,再推荐穿搭")
- 高阶:引入记忆(Memory)、规划(Planning)、工具链(Tool Chain)
推荐资源:
- 📘 OpenAI Function Calling 官方文档
- 🧱 LangChain4j:专为 Java 开发者设计的 LLM 框架
- 🌐 Hugging Face Agents 教程:开源替代方案
AI 不是取代 Web 开发者,而是赋予我们"智能胶水"的能力------把现有服务编织成会思考的系统。你缺的不是 AI 知识,而是用 Web 思维重构它的勇气。
