介绍
我一直在云端构建 llm 应用程序。我还看到很多开发人员制作 llm 应用程序,这对于 mvp 或原型来说非常好,但需要一些工作才能使其做好生产准备。应用所列出的一种或多种实践可以帮助您的应用程序以有效的方式进行扩展。本文不涵盖应用程序开发的整个软件工程方面,而仅涵盖 llm 包装应用程序。此外,代码片段是用python编写的,相同的逻辑也可以应用于其他语言。
1. 利用中间件实现灵活性
使用 litellm 或 langchain 等中间件来避免供应商锁定,并随着模型的发展在模型之间轻松切换。
python:
from litellm import completion
response = completion(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "hello, how are you?"}]
)
像litellm和langchain这样的中间件解决方案在您的应用程序和各种llm提供商之间提供了一个抽象层。这种抽象允许您轻松地在不同模型或提供程序之间切换,而无需更改核心应用程序代码。随着人工智能领域的快速发展,不断发布具有改进功能的新模型。通过使用中间件,您可以根据性能、成本或功能要求快速采用这些新模型或切换提供商,确保您的应用程序保持最新状态并具有竞争力。
2. 实施重试机制
通过在 api 调用中实现重试逻辑来避免速率限制问题。
python:
import time
from openai import openai
client = openai()
def retry_api_call(max_retries=3, delay=1):
for attempt in range(max_retries):
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "hello!"}]
)
return response
except exception as e:
if attempt == max_retries - 1:
raise e
time.sleep(delay * (2 ** attempt)) # exponential backoff
llm 提供者经常施加费率限制,以防止滥用并确保公平使用。实施具有指数退避的重试机制可以帮助您的应用程序优雅地处理临时故障或速率限制错误。这种方法通过自动重试失败的请求来提高应用程序的可靠性,减少由于暂时性问题而导致服务中断的可能性。指数退避策略(增加重试之间的延迟)有助于防止立即重新请求使 api 不堪重负,这可能会加剧速率限制问题。
3. 设置 llm 提供商后备
不要依赖单一的法学硕士提供商。实施后备措施来处理配额问题或服务中断。
from litellm import completion
def get_llm_response(prompt):
providers = ['openai/gpt-3.5-turbo', 'anthropic/claude-2', 'cohere/command-nightly']
for provider in providers:
try:
response = completion(model=provider, messages=[{"role": "user", "content": prompt}])
return response
except exception as e:
print(f"error with {provider}: {str(e)}")
continue
raise exception("all llm providers failed")
如果该提供商遇到停机或达到配额限制,则依赖单个 llm 提供商可能会导致服务中断。通过实施后备选项,您可以确保应用程序的持续运行。这种方法还允许您利用不同提供商或模型的优势来完成各种任务。 litellm 通过为多个提供者提供统一的接口来简化此过程,使其更容易在它们之间切换或实现回退逻辑。
4. 实施可观察性
使用 langfuse 或 helicone 等工具进行 llm 跟踪和调试。
from langfuse.openai import openai
client = openai(
api_key="your-openai-api-key",
langfuse_public_key="your-langfuse-public-key",
langfuse_secret_key="your-langfuse-secret-key"
)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "hello, ai!"}]
)
实施可观察性的优点:
- 增强调试:轻松跟踪和重播对话以识别问题。
- 性能优化:深入了解响应时间和模型性能。
- 成本管理:跟踪代币使用情况和相关成本,以更好地控制预算。
- 质量保证:监控响应的质量并确定需要改进的领域。
- 用户体验分析:了解用户交互并相应优化提示。
- 合规性和审计:维护监管合规性和内部审计的日志。
- 异常检测:快速识别并响应异常模式或行为。
可观察性工具为您的 llm 应用程序的性能、使用模式和潜在问题提供重要的见解。它们允许您实时监控和分析与法学硕士的交互,帮助您优化提示、识别瓶颈并确保人工智能生成的响应的质量。随着时间的推移,这种可见性级别对于维护、调试和改进应用程序至关重要。
5. 有效管理提示
使用带有版本控制的提示管理工具,而不是在代码或文本文件中硬编码提示。
from promptflow import promptflow
pf = promptflow()
prompt_template = pf.get_prompt("greeting_prompt", version="1.2")
response = openai.chatcompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt_template.format(name="alice")}]
)
有效的及时管理对于维护和改进您的llm申请至关重要。通过使用专用的提示管理工具,您可以对提示进行版本控制、a/b 测试不同的变体,并在您的应用程序中轻松更新它们。这种方法将提示逻辑与应用程序代码分开,使得在不更改核心应用程序的情况下更容易迭代提示。它还使非技术团队成员能够为快速改进做出贡献,并在改进人工智能交互方面实现更好的协作。
6. 持久存储对话历史记录
使用像redis这样的持久缓存来存储会话历史记录,而不是不适合分布式系统的内存缓存。
from langchain.memory import redischatmessagehistory
from langchain.chains import conversationchain
from langchain.llms import openai
# initialize redis chat message history
message_history = redischatmessagehistory(url="redis://localhost:6379/0", ttl=600, session_id="user-123")
# create a conversation chain with redis memory
conversation = conversationchain(
llm=openai(),
memory=message_history,
verbose=true
)
# use the conversation
response = conversation.predict(input="hi there!")
print(response)
# the conversation history is automatically stored in redis
存储对话历史记录对于维护持续交互中的上下文和提供个性化体验至关重要。使用像 redis 这样的持久缓存,尤其是在分布式系统中,可以确保可靠地存储对话历史记录并快速访问。这种方法允许您的应用程序水平扩展,同时在不同实例或服务器上保持一致的用户体验。将 redis 与 langchain 结合使用可以简化将持久内存集成到对话式 ai 系统中的过程,从而更轻松地构建有状态、上下文感知的应用程序。
7. 尽可能使用 json 模式
尽可能提供 json 模式(例如提取结构化信息),而不是依赖原始文本输出。
import openai
response = openai.chatcompletion.create(
model="gpt-3.5-turbo-1106",
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": "extract the name and age from the user's input."},
{"role": "user", "content": "my name is john and i'm 30 years old."}
]
)
print(response.choices[0].message.content)
# output: {"name": "john", "age": 30}
使用json模式进行信息提取提供了结构化且一致的输出格式,使得您的应用程序中更容易解析和处理llm的响应。这种方法减少了对自由格式文本进行复杂的后处理的需要,并最大限度地降低了误解的风险。它对于表单填写、非结构化文本数据提取等任务特别有用,或者需要将 ai 生成的内容集成到现有数据结构或数据库中的任何场景。
8. 设置信用警报
即使在 mvp 阶段,也对预付信用和每用户信用检查实施警报。
def check_user_credits(user_id, requested_tokens):
user_credits = get_user_credits(user_id)
if user_credits
<p>实施信用警报和每用户信用检查对于管理成本和确保法学硕士申请的公平使用至关重要。该系统有助于防止意外费用,并允许您根据信用额度主动管理用户访问。通过在多个阈值设置警报,您可以在积分耗尽之前通知用户或管理员,确保服务不间断。即使在 mvp 阶段,这种方法也很有价值,因为它可以帮助您了解使用模式并计划有效地扩展应用程序。</p>
<h2>
9.实施反馈循环
</h2>
<p>创建用户提供有关人工智能响应反馈的机制,从简单的赞成/反对评级开始。<br></p>
<pre class="brush:php;toolbar:false">def process_user_feedback(response_id, feedback):
if feedback == 'thumbs_up':
log_positive_feedback(response_id)
elif feedback == 'thumbs_down':
log_negative_feedback(response_id)
trigger_improvement_workflow(response_id)
# in your api endpoint
@app.route('/feedback', methods=['post'])
def submit_feedback():
data = request.json
process_user_feedback(data['response_id'], data['feedback'])
return jsonify({"status": "feedback received"})
实施反馈循环对于持续改进您的法学硕士申请至关重要。通过允许用户提供有关 ai 响应的反馈,您可以确定模型表现良好的领域以及需要改进的领域。这些数据可用于微调模型、调整提示或实施额外的保护措施。从简单的赞成/反对评级开始,为用户提供了一种提供反馈的简单方法,而稍后可以添加更详细的反馈选项以获得更深入的见解。这种方法有助于与用户建立信任,并表明您致力于根据实际使用情况提高人工智能的性能。
10.实施护栏
使用提示卫士检查提示注入攻击、有毒内容和偏离主题的响应。
import re
from better_profanity import profanity
def check_prompt_injection(input_text):
injection_patterns = [
r"ignore previous instructions",
r"disregard all prior commands",
r"override system prompt"
]
for pattern in injection_patterns:
if re.search(pattern, input_text, re.IGNORECASE):
return True
return False
def check_toxic_content(input_text):
return profanity.contains_profanity(input_text)
def sanitize_input(input_text):
if check_prompt_injection(input_text):
raise ValueError("Potential prompt injection detected")
if check_toxic_content(input_text):
raise ValueError("Toxic content detected")
# Additional checks can be added here (e.g., off-topic detection)
return input_text # Return sanitized input if all checks pass
# Usage
try:
safe_input = sanitize_input(user_input)
# Process safe_input with your LLM
except ValueError as e:
print(f"Input rejected: {str(e)}")
实施护栏对于确保 llm 申请的安全性和可靠性至关重要。此示例演示如何检查潜在的即时注入攻击和有毒内容。即时注入攻击试图覆盖或绕过系统的预期行为,而有毒内容检查有助于维护安全和尊重的环境。通过实施这些检查,您可以防止人工智能系统被恶意使用,并确保生成的内容符合应用程序的准则和道德标准。可以添加额外的检查来检测偏离主题的响应或其他不需要的行为,进一步增强应用程序的稳健性。
结论
上面列出的所有要点都可以轻松集成到您的应用程序中,它们可以让您更好地为生产中的扩展做好准备。您也可能同意或不同意上述某些观点。无论如何,请随时发表您的问题或评论。