DeskLLM 技术文档¶
1. 概述¶
DeskLLM 是一个模拟桌面环境的大语言模型封装框架,它提供了一个统一的接口来与各种大语言模型进行交互。DeskLLM 的设计理念是将大模型视为一个拥有自己桌面环境的智能体,它可以在这个环境中执行各种任务,如编辑文件、运行代码等。
DeskLLM 的核心优势在于: - 统一的接口设计,便于切换不同的底层大语言模型 - 丰富的提示词管理机制,支持多种提示词模板 - 灵活的上下文管理,包括系统消息、指令消息、工作环境状态等 - 支持工具调用和中间结果处理
2. 架构设计¶
DeskLLM 采用了抽象基类 + 具体实现的设计模式:
GenerationLLM (抽象基类)
└── DeskLLM (抽象基类)
├── GPTDesk (OpenAI 实现)
├── ClaudeDesk (Anthropic 实现)
└── DeepSeekDesk (DeepSeek 实现)
每个具体实现类负责与特定的 LLM 服务提供商 API 进行交互,而共享相同的接口和基础功能。
3. 核心组件¶
3.1 提示词管理¶
DeskLLM 将提示词分为多个类别,每个类别都有特定的用途:
- system_prompt: 系统消息提示,用于限定大模型角色、工具范围及提供背景信息
- instruction_prompt: 指令消息提示,通过 few-shot 学习方式提供示例
- original_desk_screenshot_prompt: 初始工作环境状态,描述任务初始时的环境
- purpose_prompt: 任务目的提示,提供任务目标和要求
- intermediate_prompt: 中间结果提示,记录 LLM 生成的中间结果和状态变更
- current_desk_screenshot_prompt: 当前工作环境状态,描述任务进行时的环境状态
3.2 模板系统¶
DeskLLM 支持多种提示词模板系统,推荐使用 Jinja2PromptTemplate:
- 支持条件语句、循环和宏定义
- 支持多语言模板
- 支持自定义过滤器和全局函数
3.3 请求处理流程¶
- 构造请求参数 (construct_request_params)
- 发送请求到 LLM API (complete/async_complete)
- 处理响应并构造结果 (construct_llm_result)
4. 实现原则与注意事项¶
4.1 基本原则¶
- 接口一致性:所有 DeskLLM 的实现类应保持相同的接口,便于切换不同的底层模型
- 错误处理:实现应包含完善的错误处理机制,特别是网络错误和 API 限制错误
- 上下文管理:合理管理上下文长度,避免超出模型的最大上下文窗口
- 参数验证:使用 Pydantic 进行参数验证,确保参数的正确性
- 异步支持:同时提供同步和异步接口,满足不同场景的需求
4.2 注意事项¶
- 响应格式限制:DeskLLM 仅支持纯文本返回,不支持 JSON Schema 格式
- 上下文窗口管理:当上下文超出限制时,应有策略进行上下文压缩
- 代理配置:在网络受限环境中,需要正确配置代理
- API 密钥管理:安全存储和使用 API 密钥
- 重试机制:对于可重试的错误(如网络超时),应实现适当的重试策略
5. 最佳实践¶
5.1 模型选择¶
根据任务复杂度和性能要求选择合适的模型:
- 简单任务:可使用轻量级模型如 GPT-3.5-Turbo
- 复杂推理:推荐使用高级模型如 GPT-4、Claude-3-Opus 或 DeepSeek-Reasoning
- 中文场景:DeepSeek 模型在中文处理上有较好表现
5.2 提示词设计¶
- 使用 Jinja2 模板:优先使用 Jinja2PromptTemplate 而非 FStrPromptTemplate
- 分层提示词:合理利用不同类型的提示词,清晰分离系统指令、用户输入和环境状态
- 保持简洁:避免冗余信息,减少 token 消耗
- 结构化信息:对于复杂信息,使用结构化格式呈现
5.3 工具集成¶
- 工具描述:提供清晰的工具描述和参数说明
- 错误处理:处理工具执行过程中可能出现的错误
- 结果反馈:将工具执行结果正确反馈给模型
5.4 代码示例¶
基本使用示例¶
from tfrobot.brain.chain.llms.generation_llms.desk_llm.openai_desk import GPTDesk
from tfrobot.brain.chain.prompt.template.jinja2_template import Jinja2PromptTemplate
from tfrobot.brain.chain.prompt.memo_prompt import MemoPrompt
from tfrobot.schema.message.conversation.message_dto import TextMessage
from tfrobot.schema.types import Locale
from tfrobot.schema.users import BaseUser
# 创建 DeskLLM 实例
desk_llm = GPTDesk(
name="gpt-4-turbo-preview",
openai_api_key="your_api_key",
temperature=0.7
)
# 添加系统提示
system_template = Jinja2PromptTemplate(
templates={
Locale.EN: "You are a helpful assistant that specializes in coding.",
Locale.ZH: "你是一个专注于编程的助手。"
}
)
memo_prompt = MemoPrompt()
desk_llm.system_prompt.append(memo_prompt)
# 创建用户输入
user_input = TextMessage(
role="user",
creator=BaseUser(name="User", uid="1"),
content="帮我写一个简单的 Python 函数来计算斐波那契数列"
)
# 获取响应
result = desk_llm.complete(current_input=user_input)
print(result.generations[0].text)
工具调用示例¶
from tfrobot.brain.chain.llms.generation_llms.desk_llm.openai_desk import GPTDesk
from tfrobot.brain.chain.prompt.tool_prompt import ToolPrompt
from tfrobot.drive.tool.tool import tool
# 定义工具
@tool
def calculate(expression: str) -> str:
"""计算数学表达式的结果"""
try:
return str(eval(expression))
except Exception as e:
return f"Error: {str(e)}"
# 创建 DeskLLM 实例
desk_llm = GPTDesk(name="gpt-4-turbo-preview", openai_api_key="your_api_key")
# 添加工具提示
tool_prompt = ToolPrompt()
desk_llm.system_prompt.append(tool_prompt)
# 使用工具
result = desk_llm.complete(
current_input=TextMessage(content="计算 123 + 456 的结果"),
tools=[calculate]
)
6. 扩展 DeskLLM¶
6.1 创建新的 DeskLLM 实现¶
要为新的 LLM 服务提供商创建 DeskLLM 实现,需要:
- 继承 DeskLLM 抽象基类
- 实现必要的方法:
- model_post_init: 初始化客户端
- construct_request_params: 构造请求参数
- complete: 同步请求处理
- async_complete: 异步请求处理
- construct_llm_result: 构造结果对象
6.2 自定义提示词模板¶
可以通过继承 BasePrompt 和使用 Jinja2PromptTemplate 创建自定义提示词模板:
from tfrobot.brain.chain.prompt.base import BasePrompt
from tfrobot.brain.chain.prompt.template.jinja2_template import Jinja2PromptTemplate
from tfrobot.schema.meta.tf_field import TFField
from tfrobot.schema.types import Locale
class CustomPrompt(BasePrompt):
template = TFField(
default_factory=lambda: Jinja2PromptTemplate(
templates={
Locale.EN: "Custom template: {{ variable }}",
Locale.ZH: "自定义模板: {{ variable }}"
}
)
)
7. 故障排除¶
7.1 常见问题¶
- 上下文长度超限:
- 症状:API 返回 "context_length_exceeded" 错误
-
解决方案:减少提示词长度,或使用 collapse_context 方法压缩上下文
-
API 认证失败:
- 症状:API 返回 401 错误
-
解决方案:检查 API 密钥是否正确,是否过期
-
网络超时:
- 症状:请求超时错误
- 解决方案:增加 timeout 参数,或配置代理
7.2 调试技巧¶
- 使用 warnings 模块记录非致命错误
- 检查 LLMResult 中的 meta_info 字段获取额外信息
- 使用 prompt 字段查看实际发送给 API 的提示词
8. 总结¶
DeskLLM 提供了一个强大而灵活的框架,用于与各种大语言模型进行交互。通过遵循本文档中的原则和最佳实践,可以有效地利用 DeskLLM 构建高质量的 AI 应用。
关键要点: - 使用统一接口简化模型切换 - 合理组织提示词结构 - 优先使用 Jinja2 模板 - 妥善处理错误和边界情况 - 根据任务需求选择合适的模型