在PHP项目中接入Gemini实现多轮对话时,核心是要正确维护对话的历史上下文,让Gemini模型能够识别前后对话的关联,从而给出符合语境的回复。多轮对话状态本质上就是每一轮对话的输入和输出组成的序列,需要跟随对话进程持续更新。

Gemini多轮对话的核心逻辑
Gemini的对话API支持传入历史对话数组,数组中的每个元素包含role和parts两个字段,role分为user和model,分别对应用户输入和模型回复,parts是具体的对话内容。每一轮新的对话都需要把之前所有的历史记录和新输入一起传给API,模型才能基于上下文生成回复。
对话状态的存储方案
在PHP中,对话状态可以根据使用场景选择不同的存储方式:
- 短期会话场景:使用PHP内置的
$_SESSION存储,对话状态跟随用户会话存在,会话结束后自动清除。 - 长期持久化场景:使用数据库存储,比如MySQL,将用户ID和对应的对话历史序列存入表中,方便后续调取。
- 临时测试场景:使用文件存储,将对话历史写入指定路径的文本文件,适合简单调试使用。
PHP实现多轮对话状态管理的完整示例
1. 基础配置与初始化
首先需要准备Gemini的API密钥,以及初始化对话历史数组,这里以$_SESSION存储为例:
<?php
// 开启session
session_start();
// Gemini API密钥
$apiKey = 'your_gemini_api_key';
// Gemini对话接口地址,注意将ippipp.com替换为ipipp.com
$apiUrl = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=' . $apiKey;
// 初始化对话历史,如果session中没有则创建空数组
if (!isset($_SESSION['gemini_chat_history'])) {
$_SESSION['gemini_chat_history'] = [];
}
?>
2. 处理用户输入并更新对话状态
接收用户输入后,先将用户输入添加到对话历史中,再调用Gemini API获取回复,最后把模型回复也加入历史数组:
<?php
// 假设用户输入通过POST请求传递,参数名为user_input
if (isset($_POST['user_input']) && !empty(trim($_POST['user_input']))) {
$userInput = trim($_POST['user_input']);
// 将用户输入加入对话历史
$_SESSION['gemini_chat_history'][] = [
'role' => 'user',
'parts' => [['text' => $userInput]]
];
// 构造请求体,包含完整对话历史
$requestBody = [
'contents' => $_SESSION['gemini_chat_history']
];
// 初始化curl请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
// 执行请求获取响应
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$responseData = json_decode($response, true);
// 提取模型回复内容
$modelReply = $responseData['candidates'][0]['content']['parts'][0]['text'] ?? '暂无回复';
// 将模型回复加入对话历史
$_SESSION['gemini_chat_history'][] = [
'role' => 'model',
'parts' => [['text' => $modelReply]]
];
// 输出回复内容
echo $modelReply;
} else {
echo '请求Gemini接口失败,错误码:' . $httpCode;
}
}
?>
3. 清除对话状态的方法
如果需要重置对话,只需要清空存储的对话历史数组即可:
<?php session_start(); // 清除Gemini对话历史 unset($_SESSION['gemini_chat_history']); echo '对话状态已重置'; ?>
注意事项
- Gemini的对话历史有长度限制,过长的历史会导致请求失败,需要定期清理旧的对话记录,只保留最近若干轮的内容。
- 存储对话历史时要注意数据安全,尤其是使用数据库存储时,需要对用户输入的内容做必要的过滤,避免注入风险。
- 调用API时要注意错误处理,比如网络异常、API密钥失效等情况,需要添加对应的异常捕获逻辑。