整体架构概览

在开始写代码之前,理解整个系统如何协作至关重要。您的 PHP 智能体将不仅仅是调用 API,而是成为一个拥有长期记忆(知识库)和思维逻辑(提示词)的系统




这个流程图展示了整个智能体的核心工作流程:先将用户问题向量化,再用其检索知识库,将检索结果与原始问题组合成增强提示词,最后发送给大模型得到最终回复。


第一部分:核心组件与准备工作

你需要以下几个核心部分:

  1. DeepSeek API 账号与密钥:访问 DeepSeek 官网 注册并获取你的 API Key。

  2. PHP 环境:确保你的 PHP 环境版本在 7.4 以上,并启用 cURL 扩展。

  3. 向量数据库是的,你需要一个向量数据库。 虽然理论上你可以用 PHP 和 MySQL 手动计算余弦相似度,但对于任何严肃的项目,这都非常低效且不实用。向量数据库为此类检索进行了高度优化。

    • 推荐选择

      • Chroma: 轻量级、开源、易于上手,适合原型和中小项目。

      • Weaviate: 功能强大,开源,支持多种模块。

      • Qdrant: 性能优异,Rust 编写,开源。

      • Pinecone: 全托管服务,无需运维,但付费。

  4. 知识库数据:你要让智能体学习的文档、PDF、网页内容等。


第二部分:知识库与向量化

这是让你的智能体变得“聪明”和“专业”的关键。

步骤 1: 数据预处理与分块

原始文档不能直接使用,需要清洗和分割。

  • 清洗:去除无关的格式、HTML 标签等,提取纯文本。

  • 分块:将长文本分割成更小的段落(例如 256-512 个字符)。这是因为 Embedding 模型有输入长度限制,并且检索时需要返回最相关的片段,而不是整个文档。

  • 分块策略:按段落、按标题、使用滑动窗口等。合理的分块能极大影响检索质量。

步骤 2: 文本向量化

  • 什么是向量化:使用 DeepSeek 提供的 Embedding API,将每一段文本转换成一个高维数值向量(一长串数字,例如 1536 维)。这个向量在数学上代表了文本的“语义”。

  • 如何操作

    1. 调用 DeepSeek 的 Embedding 端点 (https://api.deepseek.com/v1/embeddings)。

    2. 将分块后的文本数组发送过去。

    3. 获取返回的向量数组。

PHP 代码示例:文本向量化


<?phpfunction get_embedding($text, $api_key) {
 $url = 'https://api.deepseek.com/v1/embeddings';
 
 $headers = [
  'Authorization: Bearer ' . $api_key,
  'Content-Type: application/json',
 ];
 
 $data = [
  'input' => $text, // 可以是字符串或字符串数组
  'model' => 'deepseek-embedding', // 确认最新的embedding模型名称
 ];
 
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
 curl_setopt($ch, CURLOPT_POST, true);
 curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
 $response = curl_exec($ch);
 curl_close($ch);
 
 $result = json_decode($response, true);
 
 if (isset($result['data'][0]['embedding'])) {
  return $result['data'][0]['embedding']; // 返回单个向量的数组
 } elseif (isset($result['data'])) {
  // 如果是批量处理,返回所有向量的数组
  return array_column($result['data'], 'embedding');
 } else {
  throw new Exception("Embedding API 错误: " . $response);
 }}// 用法示例$api_key = '你的_DEEPSEEK_API_KEY';$chunk_text = "这是你知识库中的一段文本...";$vector = get_embedding($chunk_text, $api_key);// $vector 现在是一个浮点数数组,例如 [0.123, -0.456, 0.789, ...]?>

步骤 3: 存储到向量数据库

将文本块和其对应的向量一起存储到向量数据库中。

  • 通常需要存储三条信息:

    1. id: 唯一标识。

    2. vector: 上一步得到的向量。

    3. text 或 metadata: 原始的文本块以及其他元数据(如来源文件、标题等)。

以 Chroma 为例的概念性步骤(具体代码取决于你用的客户端):

  1. 创建或连接一个集合。

  2. 将 idsembeddings (vectors), metadatas (包含原始文本) 批量添加到集合中。


第三部分:提示词与知识库的交互 - 推理过程

这是智能体“思考”的核心。流程是:用户提问 -> 检索知识库 -> 构建增强提示词 -> 调用 DeepSeek Chat API -> 返回答案

步骤 1: 用户提问并向量化检索

  1. 接收用户输入的问题 $user_query

  2. 使用同样的 Embedding 模型将 $user_query 转换为向量。

  3. 用这个查询向量去向量数据库中执行相似性搜索(例如余弦相似度)。

  4. 数据库返回最相似的 K 个文本块(例如 top 3)。

步骤 2: 构建系统提示词

这是最巧妙的一步。你不能直接把问题和答案扔给模型,而是要“引导”它。

  • 系统提示词:定义模型的角色和回答规则。

  • 上下文注入:将上一步检索到的相关文本块,作为“上下文”插入到提示词中。

提示词模板示例:


你是一个专业的客服助手,请严格根据以下【已知信息】来回答用户的问题。如果你不知道答案,请直接说“根据已知信息无法回答该问题”,不要编造答案。

#【已知信息】
{context}

#【用户问题】
{question}

PHP 代码示例:构建提示词并调用 Chat API



<?phpfunction ask_deepseek($user_query, $retrieved_texts, $api_key) {
 $url = 'https://api.deepseek.com/v1/chat/completions';
 
 // 1. 构建系统提示词,注入检索到的知识
 $context = implode("\n\n", $retrieved_texts); // 将检索到的多个文本块合并
 $system_message = "你是一个专业的助手,请严格根据以下【已知信息】来回答用户的问题。\n\n#【已知信息】\n" . $context . "\n\n如果你不知道答案,请直接说“根据已知信息无法回答该问题”,不要编造答案。";
 
 $headers = [
  'Authorization: Bearer ' . $api_key,
  'Content-Type: application/json',
 ];
 
 // 2. 构建请求数据
 $data = [
  'model' => 'deepseek-chat', // 例如 deepseek-v2
  'messages' => [
   ['role' => 'system', 'content' => $system_message],
   ['role' => 'user', 'content' => $user_query]
  ],
  'temperature' => 0.1, // 低温度,让答案更确定,更依赖于知识库
  'max_tokens' => 2000
 ];
 
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
 curl_setopt($ch, CURLOPT_POST, true);
 curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
 $response = curl_exec($ch);
 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 curl_close($ch);
 
 if ($httpCode !== 200) {
  throw new Exception("API 请求失败: " . $response);
 }
 
 $result = json_decode($response, true);
 return $result['choices'][0]['message']['content'];}// --- 整体流程示例 ---$api_key = "你的_DEEPSEEK_API_KEY";$user_question = $_POST['question']; // 从Web表单获取问题// 1. 将用户问题向量化$query_vector = get_embedding($user_question, $api_key);// 2. 查询向量数据库 (这里用伪代码,取决于你用的向量DB客户端)$retrieved_chunks = $vectorDBClient->query($query_vector, $top_k=3);// $retrieved_chunks 是一个数组,包含元数据,我们需要里面的文本$retrieved_texts = array_column($retrieved_chunks, 'text');// 3. 调用上面定义的函数,获取最终答案$final_answer = ask_deepseek($user_question, $retrieved_texts, $api_key);// 4. 将 $final_answer 输出给用户echo $final_answer;?>

第四部分:总结与最佳实践

  1. 流程是不可逆的:知识库处理(向量化)是一次性的预处理步骤。而用户的每次提问都会触发后面的完整推理流程。

  2. 提示词工程是关键:系统提示词的质量直接决定答案的准确性。多迭代和测试你的提示词,比如要求模型“引用来源”、“分点回答”等。

  3. 向量数据库是必需的:对于任何有实际用途的知识库系统,向量数据库在性能和准确性上都是不可或缺的。

  4. 分块策略需要调试:块太大,会包含无关信息;块太小,会丢失上下文。这是需要根据你的数据源反复实验的。

  5. 成本考量:Embedding 和 Chat 都要收费。预处理知识库时会有一次性的 Embedding 成本。每次用户提问会触发 1 次 Embedding(问题) + 1 次 Chat。

  6. 安全性:不要将 API Key 暴露在前端,所有操作都应在你的 PHP 后端完成。

通过以上步骤,你就可以搭建一个真正理解你专业知识的、能够引用资料回答问题的智能体,而不仅仅是一个普通的聊天机器人。


点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部