回答生成过程
本文将详细说明 llmGenerate()
的完整流程,以及如何通过检索到的上下文进行提示词(prompt)拼接。
完整的 RAG 流程¶
1. 向量嵌入与检索(向量影响上下文选择)
// worker.ts(第 45-55 行)
const embedder = createEmbedder(env);
const [qv] = await embedder.embed([message], Number(env.EMBED_DIM));
// 使用向量检索相关上下文,但向量不会传递给 LLM
const { contexts, sources } = await getRelevantDocuments(env, qv, 8);
2. 通过 buildPrompt()
进行提示词拼接
// worker.ts(第 61 行)
const prompt = buildPrompt(message, contexts, history, language);
3. 使用 qwen-turbo-latest 进行 LLM 生成
// worker.ts(第 64 行)
const answer = await llmGenerate(env, prompt);
buildPrompt()
如何构建最终提示词¶
buildPrompt()
函数会创建一个结构化的提示词,内容包括:
**提示词结构(中文示例):**
你是 Jimmy Song,一位经验丰富的云原生架构师、技术博主和开源爱好者。这个知识库包含了你博客中的个人思考、见解和经验。
你的个性和风格:
- 你对 AI、云原生技术、服务网格(特别是 Istio)、Kubernetes 和新兴技术充满热情
- 你喜欢探索新工具,并分享来自实际经验的实用见解
[...个性化指导...]
--- 我的博客内容 ---
Istio 是一个开源的服务网格平台。它提供了连接、保护、控制和监测微服务的统一方式。
---
Istio 的核心功能包括流量管理、安全性、可观测性和策略执行。
--- 对话历史 ---
用户:你知道 Kubernetes 吗?
助手:是的,Kubernetes 是一个容器编排平台。
--- 问题 ---
Istio 是什么?
请基于知识库片段提供简洁而有针对性的回答。直接回应问题的核心,使用最相关的信息。保持回答清晰明了。重要:请不要在回答中包含任何来源链接、网址、文件路径或引用路径,这些信息由系统单独处理:
llmGenerate()
如何处理提示词¶
对于 qwen-turbo-latest 模型,API 调用结构如下:
// llm.ts(第 34-54 行)
if (env.PROVIDER === 'qwen') {
const url = env.QWEN_CHAT_BASE || 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
const body = {
model: env.LLM_MODEL || 'qwen-plus', // 此处实际使用 'qwen-turbo-latest'
messages: [
{ role: 'system', content: '请用中文回答,并在末尾列出来源路径。' },
{ role: 'user', content: prompt } // 完整拼接的提示词
]
};
}
关键点:向量不会直接传递给 LLM¶
重点说明:嵌入向量不会直接传递给 LLM,具体流程如下:
- 向量用于相似度检索,在 Vectorize 数据库中查找相关文档片段
- 从检索到的文档中提取文本上下文
- 只有文本上下文会被包含在发送给 qwen-turbo-latest 的提示词中
- LLM 接收的是结构化文本,而不是数值向量
模型响应示例¶
对于类似“Istio 是什么?”的提问,qwen-turbo-latest 会收到上述结构化提示词,并返回如下精简回答:
{
"choices": [{
"message": {
"content": "Istio 是一个开源的服务网格平台,专门用于微服务架构。基于我的实际使用经验,它的核心价值在于:\n\n**核心功能:**\n- **流量管理**:提供智能路由、负载均衡和流量分割能力\n- **安全性**:实现服务间的双向 TLS 认证和访问控制\n- **可观测性**:自动收集服务间的遥测数据\n- **策略执行**:统一的策略管理和执行框架\n\n在实际项目中,我发现 Istio 最大的优势是能够在不修改应用代码的情况下,为微服务提供统一的连接、保护、控制和监测能力..."
}
}]
}
系统随后会提取 content 字段,并将其与检索阶段单独追踪的来源信息一并返回。