作为一名长期使用LlamaIndex构建AI应用的开发者,我发现很多刚接触这个框架的同行往往只停留在基础功能的使用上,而忽略了其强大的提示工程能力。今天我将分享四种在实际项目中经过验证的高级提示技术,这些技巧能让你的LLM应用开发效率提升至少50%。
在开始之前,我们需要确保环境配置正确。LlamaIndex的模块化设计让我们可以按需安装组件:
bash复制pip install llama-index-core llama-index-llms-openai llama-index-embeddings-openai
注意:建议使用Python 3.8+环境,避免依赖冲突。如果使用Jupyter Notebook,可以用%pip代替pip。
安全地配置API密钥是项目的第一步。我推荐使用环境变量而非硬编码:
python复制import os
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
# 最佳实践:从配置文件或密钥管理服务加载密钥
os.environ["OPENAI_API_KEY"] = "你的实际密钥"
# 全局模型配置
Settings.llm = OpenAI(
model="gpt-3.5-turbo",
temperature=0.1 # 控制创造性,分析型任务建议0.1-0.3
)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
部分格式化(Partial Formatting)是我在开发工作流中最常用的技术之一。它允许我们分阶段构建提示,特别适合多步骤处理场景。
python复制from llama_index.core.prompts import PromptTemplate
qa_template = """
作为{role},请根据以下上下文回答问题。
上下文:
{context}
问题:{question}
答案:
"""
prompt = PromptTemplate(qa_template)
# 第一阶段:固定角色参数
analyst_prompt = prompt.partial_format(role="资深数据分析师")
# 第二阶段:动态注入上下文和问题
final_prompt = analyst_prompt.format(
context="2023年Q4销售额增长15%",
question="增长的主要驱动力是什么?"
)
实际应用场景:
当需要复用现有模板但变量名不匹配时,变量映射技术能节省大量重构时间。我在迁移旧项目时经常使用这个方法。
python复制legacy_template = """
用户咨询:{user_query}
相关文档:{doc_text}
请生成回复:
"""
# 建立新旧变量名映射
var_mapping = {
"query_str": "user_query",
"context_str": "doc_text"
}
adapted_prompt = PromptTemplate(
legacy_template,
template_var_mappings=var_mapping
)
# 使用标准接口调用
response = adapted_prompt.format(
query_str="如何退款?",
context_str="退款政策:7天内无理由退款..."
)
典型使用场景:
这是最强大的技术之一,允许在提示生成时执行动态数据处理。我在构建智能客服系统时大量使用了这种方法。
python复制def enhance_context(**kwargs):
"""自动增强原始上下文"""
raw_text = kwargs["context_str"]
# 添加自动摘要
summary = f"摘要:{raw_text[:50]}..."
# 添加结构化标记
return f"[增强版]\n{summary}\n\n完整内容:\n{raw_text}"
qa_template = """
请根据以下增强后的上下文回答问题:
{context_str}
问题:{query_str}
"""
prompt = PromptTemplate(
qa_template,
function_mappings={"context_str": enhance_context}
)
# 自动应用增强函数
final_prompt = prompt.format(
context_str="LlamaIndex是一个...",
query_str="LlamaIndex的主要功能是什么?"
)
进阶技巧:
通过结合向量检索,我们可以实现真正的上下文感知提示。我在构建专业领域QA系统时,这个技术将准确率提升了40%。
python复制from llama_index.core import VectorStoreIndex, Document
# 准备示例库
examples = [
"问题:销售增长率怎么算?\n解答:(本期销售额-上期销售额)/上期销售额",
"问题:什么是环比?\n解答:与相邻上期数据对比"
]
index = VectorStoreIndex.from_documents(
[Document(text=e) for e in examples]
)
def retrieve_examples(**kwargs):
query = kwargs["query_str"]
retriever = index.as_retriever(similarity_top_k=2)
return "\n".join([n.text for n in retriever.retrieve(query)])
qa_template = """
参考以下类似问题的解答:
{examples}
请回答:
问题:{query_str}
答案:
"""
prompt = PromptTemplate(
qa_template,
function_mappings={"examples": retrieve_examples}
)
# 自动获取相关示例
response = prompt.format(query_str="如何计算利润增长率?")
性能优化建议:
经过多个项目实践,我总结了以下性能优化方法:
python复制# 好的做法
cached_prompt = PromptTemplate(template_str)
# 不好的做法:每次重新创建
def get_response():
return PromptTemplate(template_str).format(...)
python复制questions = ["Q1", "Q2", "Q3"]
# 一次性生成所有提示
prompts = [prompt.partial_format(q=q) for q in questions]
python复制from functools import lru_cache
@lru_cache(maxsize=100)
def get_enhanced_context(text):
# 处理逻辑...
问题1:变量未填充导致模板错误
python复制# 添加默认值
prompt = PromptTemplate(template, default_var="未提供")
问题2:函数映射性能瓶颈
python复制# 1. 检查函数复杂度
# 2. 添加缓存
# 3. 考虑异步处理
问题3:少样本示例不相关
python复制# 改进检索策略
retriever = index.as_retriever(
similarity_top_k=3,
vector_store_query_mode="hybrid" # 混合检索
)
将多种技术组合使用可以构建强大的处理流水线:
python复制# 分阶段提示处理流水线
def create_analysis_pipeline():
# 第一阶段:固定分析框架
base = prompt.partial_format(role="分析师", format="Markdown")
# 第二阶段:添加数据处理函数
with_functions = base.copy()
with_functions.function_mappings = {
"data": preprocess_data,
"context": retrieve_relevant_regulations
}
# 第三阶段:动态示例
final = with_functions.copy()
final.function_mappings["examples"] = get_industry_examples
return final
pipeline = create_analysis_pipeline()
基于输入内容智能选择最适合的模板:
python复制def get_dynamic_template(query):
if "比较" in query:
return comparison_template
elif "分析" in query:
return analysis_template
else:
return default_template
selected = get_dynamic_template(user_input)
response = selected.format(...)
在长期的项目实践中,我总结了以下关键安全准则:
python复制import html
def safe_format(text):
return html.escape(text)
python复制from presidio_analyzer import AnalyzerEngine
analyzer = AnalyzerEngine()
results = analyzer.analyze(text=text, language="zh")
python复制class ProtectedPrompt:
def __init__(self, template):
self._template = template
@property
def template(self):
return self._template # 只读访问