LLM 最佳实践与性能优化
本文档汇总了使用 TFRobot LLM 模块的最佳实践和性能优化技巧。
模型选择
按场景选择
| 场景 |
推荐模型 |
原因 |
| 通用对话 |
GPT-4o, Claude 3.5 Sonnet |
综合能力最强 |
| 复杂推理 |
Claude 3.5 Sonnet (Extended Thinking) |
推理过程可见 |
| 长文档分析 |
Gemini 1.5 Pro, Claude Opus |
上下文窗口大 |
| 代码生成 |
GPT-4o, Claude 3.5 Sonnet |
代码能力强 |
| 中文场景 |
DeepSeek, GLM |
中文理解好 |
| 成本敏感 |
GPT-4o-mini, Claude Haiku |
价格低 |
| 快速响应 |
GPT-4o-mini, Claude Haiku |
延迟低 |
| 本地部署 |
Ollama (Llama 3) |
数据隐私 |
成本对比
| 模型 |
输入价格 |
输出价格 |
性价比 |
| GPT-4o |
¥0.025/1M |
¥0.05/1M |
⭐⭐⭐⭐ |
| Claude 3.5 Sonnet |
¥0.015/1M |
¥0.0375/1M |
⭐⭐⭐⭐⭐ |
| Gemini 1.5 Pro |
¥0.00875/1M |
¥0.02625/1M |
⭐⭐⭐⭐⭐ |
| DeepSeek-Chat |
¥0.001/1M |
¥0.002/1M |
⭐⭐⭐⭐⭐ |
| GPT-4o-mini |
¥0.00075/1M |
¥0.0015/1M |
⭐⭐⭐⭐⭐ |
Prompt 工程
Prompt 位置策略
from tfrobot.brain.chain.llms import Claude
from tfrobot.brain.chain.prompt.memo_prompt import MemoPrompt
from tfrobot.brain.chain.prompt.tool_prompt import ToolPrompt
from tfrobot.brain.chain.prompt.knowledge_prompt import KnowledgePrompt
llm = Claude(name="claude-3-5-sonnet-20241022")
# 推荐的组织方式
llm.system_msg_prompt = [
MemoPrompt(template="你是一个专业的 Python 开发助手。"), # 1. 系统角色
ToolPrompt(), # 2. 工具列表
KnowledgePrompt(), # 3. 知识库
]
llm.before_input_msg_prompt = [
MemoPrompt(template="当前项目是一个 FastAPI Web 框架。"), # 任务背景
]
llm.after_input_msg_prompt = [
MemoPrompt(template="请使用 Markdown 格式回复。"), # 输出格式
]
llm.after_intermediate_msg_prompt = [
MemoPrompt(template="请根据工具返回结果继续完成任务。"), # 工具调用后引导
]
Prompt 模板选择
from tfrobot.brain.chain.prompt.template.jinja2_template import Jinja2PromptTemplate
from tfrobot.schema.types import Locale
# 推荐:使用 Jinja2 模板(支持条件、循环)
template = Jinja2PromptTemplate(
templates={
Locale.ZH: """
你是一个{{ role }}。
{% if tools %}
可用工具:
{% for tool in tools %}
- {{ tool.name }}: {{ tool.description }}
{% endfor %}
{% endif %}
用户问题:{{ user_input.input }}
"""
}
)
Few-Shot 学习
from tfrobot.brain.chain.llms import GPT
llm = GPT(
name="gpt-4o",
response_format={
"type": "json_schema",
"json_schema": {...},
"examples": [ # Few-shot 示例
{"name": "张三", "age": 25},
{"name": "李四", "age": 30},
]
}
)
Token 优化
上下文压缩策略
- 自动压缩:Chain 会自动触发压缩
- 手动压缩:调用
collapse_context 方法
from tfrobot.schema.exceptions import ContextTooLargeError
try:
result = llm.complete(
current_input=user_input,
conversation=long_conversation
)
except ContextTooLargeError:
# 手动压缩
compacted_conv, _, _, _, _ = llm.collapse_context(
current_input=user_input,
conversation=long_conversation,
to_size=e.target_size
)
result = llm.complete(
current_input=user_input,
conversation=compacted_conv
)
摘要模式
# 历史消息自动使用摘要模式
conversation = [...] # 长对话历史
result = llm.complete(
current_input=user_input,
conversation=conversation # 内部自动摘要
)
控制知识库大小
# 截断过长的知识库
max_knowledge_length = 5000 # tokens
if len(knowledge) > max_knowledge_length:
knowledge = knowledge[:max_knowledge_length]
使用 smaller models
# 简单任务使用更小的模型
from tfrobot.brain.chain.llms import GPT
# 复杂任务
complex_llm = GPT(name="gpt-4o")
# 简单任务
simple_llm = GPT(name="gpt-4o-mini")
工具调用优化
工具描述优化
from tfrobot.drive.tool.tool import tool
@tool
def search_code(query: str, language: str = "python") -> str:
"""
搜索代码示例
Args:
query: 搜索关键词(如 "快速排序")
language: 编程语言,支持 python、javascript、java 等
Returns:
代码示例和简要说明
Examples:
>>> search_code("快速排序", "python")
"def quicksort(arr): ..."
"""
# 工具实现
...
工具过滤
from tfrobot.brain.chain.llms import GPT
llm = GPT(
name="gpt-4o",
tool_filter="(&(Edit)(!(IDEWrite)))" # 仅使用 Tag=Edit 且名称不为 IDEWrite 的工具
)
Map-Reduce 优化
# 工具支持 Map-Reduce 模式
from tfrobot.schema.drive.tool.base import MessageCategory
@tool
def batch_process(items: list[str]) -> str:
"""
批量处理项目
Returns:
Map 模式:返回中间结果
Reduce 模式:返回最终汇总
"""
# Map 模式
yield from process_items(items)
# Reduce 模式
return summarize_results()
错误处理
统一错误处理
from tfrobot.schema.exceptions import ContextTooLargeError, TFLLMError
try:
result = llm.complete(current_input=user_input)
except ContextTooLargeError as e:
# 上下文超长
print(f"上下文超长: {e.current_size} > {e.target_size}")
# 触发压缩
compacted, _, _, _, _ = llm.collapse_context(
current_input=user_input,
conversation=conversation,
to_size=e.target_size
)
result = llm.complete(current_input=user_input, conversation=compacted)
except TFLLMError as e:
# 其他 LLM 错误
print(f"LLM 错误: {e}")
raise
except Exception as e:
# 未知错误
print(f"未知错误: {e}")
raise
重试策略
from tenacity import (
retry,
stop_after_attempt,
wait_exponential,
)
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10),
)
def call_llm_with_retry(llm, user_input):
return llm.complete(current_input=user_input)
性能优化
并发调用
import asyncio
async def batch_call_llm(llm, inputs):
tasks = [llm.async_complete(current_input=inp) for inp in inputs]
results = await asyncio.gather(*tasks)
return results
缓存
from functools import lru_cache
@lru_cache(maxsize=128)
def cached_llm_call(llm, query: str):
return llm.complete(current_input=TextMessage(content=query))
流式输出
llm = GPT(name="gpt-4o", stream=True)
result = llm.complete(current_input=user_input)
# result.generations[0].text 会逐步生成
成本控制
设置价格
llm = GPT(
name="gpt-4o",
input_price=0.005, # 5美元/百万tokens
output_price=0.015 # 15美元/百万tokens
)
统计成本
result = llm.complete(current_input=user_input)
# 查看成本
print(f"输入 tokens: {result.usage.prompt_tokens}")
print(f"输出 tokens: {result.usage.completion_tokens}")
print(f"总 tokens: {result.usage.total_tokens}")
# 计算成本
input_cost = result.usage.prompt_tokens * llm.input_price / 1000
output_cost = result.usage.completion_tokens * llm.output_price / 1000
total_cost = input_cost + output_cost
print(f"总成本: ¥{total_cost:.4f}")
使用更便宜的模型
# 简单任务使用 mini 模型
if is_simple_task(user_input):
llm = GPT(name="gpt-4o-mini")
else:
llm = GPT(name="gpt-4o")
多模态优化
图片 Detail 级别
from tfrobot.schema.message.msg_part import ImagePart
# 不需要细节时使用 low detail
ImagePart(
image_url=ImgUrl(url="path/to/image.jpg"),
detail="low" # 仅 85 tokens
)
# 需要细节时使用 high detail
ImagePart(
image_url=ImgUrl(url="path/to/image.jpg"),
detail="high" # 根据瓦片数计算
)
图片预压缩
from PIL import Image
def compress_image(image_path: str, max_size: int = 1024):
"""压缩图片以减少 token 消耗"""
img = Image.open(image_path)
# 等比缩放
img.thumbnail((max_size, max_size))
# 保存
compressed_path = image_path.replace(".", "_compressed.")
img.save(compressed_path, quality=85)
return compressed_path
遥测与调试
查看实际 Prompt
result = llm.complete(current_input=user_input)
# 查看实际发送给 LLM 的 prompt
print(result.meta_info.get("prompt"))
查看工具调用
result = llm.complete(current_input=user_input, tools=[...])
# 查看工具调用
for gen in result.generations:
if gen.tool_calls:
for tc in gen.tool_calls:
print(f"调用工具: {tc.function.name}")
print(f"参数: {tc.function.parameters}")
OpenTelemetry 追踪
from tfrobot.telemetry.tracer import tracer
@tracer.start_as_current_span("my_llm_operation")
def my_llm_function():
result = llm.complete(current_input=user_input)
return result
安全建议
API 密钥管理
# 推荐:使用环境变量
import os
api_key = os.getenv("OPENAI_API_KEY")
llm = GPT(name="gpt-4o", openai_api_key=api_key)
# 不推荐:硬编码密钥
# llm = GPT(name="gpt-4o", openai_api_key="sk-...")
输入验证
def validate_input(user_input: str) -> bool:
"""验证用户输入"""
if len(user_input) > 10000:
raise ValueError("输入过长")
# 其他验证逻辑
return True
输出过滤
def filter_output(result: LLMResult) -> str:
"""过滤输出内容"""
text = result.generations[0].text
# 过滤敏感词
# ...
return text
相关文档