跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://simplellmfunc.cn/llms.txt

Use this file to discover all available pages before exploring further.

提示词即代码

第三个设计原则:你的文档字符串就是系统提示词。提示词存在于代码中,与代码一起版本控制,像代码一样维护。

分离提示词的问题

LLM 应用中的常见模式:
  • 提示词放在 YAML/JSON 文件中,运行时加载
  • 提示词模板放在数据库中,通过 UI 编辑
  • 提示词作为字符串常量定义在远离使用位置的地方
  • 提示词由与代码库分离的”提示词工程”工具管理
所有这些都造成同一个问题:提示词漂移。提示词和使用它的代码独立演化。代码期望某些输出格式,但提示词在没有更新解析器的情况下被编辑。提示词引用了不再存在的参数。没人知道生产环境中运行的是哪个版本的提示词。

文档字符串即系统提示词

在 SimpleLLMFunc 中,函数的文档字符串就是提示词:
@llm_function(llm_interface=llm)
async def classify(text: str, categories: list[str]) -> Classification:
    """
    将文本分类到提供的类别之一。

    规则:
    - 只选择一个类别。
    - 如果没有很好的匹配,选择最接近的并将置信度设在 0.5 以下。
    - 用一句话解释你的推理。
    """
    pass
文档字符串是:
  • 同位置的 — 就在它描述的函数签名旁边
  • 版本控制的 — 像任何其他代码一样在 git 中跟踪变更
  • 类型感知的 — 框架自动添加参数类型和返回 schema
  • 可重构的 — 重命名参数,IDE 更新文档字符串引用
  • 可审查的 — PR 在同一个 diff 中显示提示词变更和代码变更

框架添加了什么

你的文档字符串是起点,而不是整个系统提示词。框架用以下内容增强它:
  1. 参数类型描述 — 从你的类型注解生成
  2. 返回类型 schema — 结构化输出格式指令
  3. 工具最佳实践 — 挂载工具时从工具文档字符串注入
  4. 输出约束 — 基于返回类型的 XML/JSON 格式规则
你写的是任务策略——模型应该做什么、质量标准是什么、遵守什么约束。框架处理结构性的管道工作。

动态提示词的模板参数

当你需要运行时可变内容在提示词中:
@llm_chat(llm_interface=llm, toolkit=[...])
async def agent(message: str, history: list | None = None):
    """
    你是 {project_name} 项目的助手。

    项目上下文:
    {project_description}

    可用命令:{command_list}
    """
    pass

# 调用时:
async for output in agent(
    "帮我解决这个 bug",
    history,
    _template_params={
        "project_name": "MyApp",
        "project_description": "一个 Web API...",
        "command_list": "build, test, deploy",
    },
):
    ...
模板在文档字符串中。值来自你的代码。两者都可追踪、可测试、有版本控制。

llm_chat:最新系统消息优先

在多轮 Agent 中,你可以通过在历史中放置 system 消息来更新系统提示词。框架使用最新的系统消息——如果历史中没有则回退到文档字符串。 这使得:
  • 基于对话状态演化的动态系统提示词
  • SelfRef 上下文注入(经验、摘要)无需修改文档字符串
  • 保持基础提示词在代码中的同时进行每轮上下文自定义

对提示词工程的影响

提示词工程变成了软件工程:
  • 测试提示词 — 用已知输入断言函数输出
  • 审查提示词 — 提示词变更经过代码审查
  • 版本化提示词 — git blame 告诉你提示词何时以及为何改变
  • 分析提示词 — 测量每个函数的延迟和 token 使用量
  • 组合提示词 — 从更小的、经过测试的提示词函数构建复杂行为
没有单独的”提示词管理”关注点。提示词就是函数。函数就是提示词。