跳转至

系统提示设计

演示如何用模板化的方式构建高质量的 system prompt:明确角色、约束、输出格式, 并支持变量插值。良好的 system prompt 是 Agent 行为可控性的基石。 对应教程:第4卷《提示工程》第1章 系统提示。

文件路径: examples/volume-04-prompt-engineering\system_prompt.py


源代码

"""系统提示(System Prompt)示例。

演示如何用模板化的方式构建高质量的 system prompt:明确角色、约束、输出格式,
并支持变量插值。良好的 system prompt 是 Agent 行为可控性的基石。

对应教程:第4卷《提示工程》第1章 系统提示。
"""

from __future__ import annotations

from dataclasses import dataclass, field
from string import Template


@dataclass
class SystemPromptBuilder:
    """系统提示构建器。

    Attributes:
        role: 助手角色描述。
        constraints: 行为约束列表。
        output_format: 期望的输出格式说明。
        extra_rules: 额外规则列表。
    """

    role: str
    constraints: list[str] = field(default_factory=list)
    output_format: str = ""
    extra_rules: list[str] = field(default_factory=list)

    def add_constraint(self, constraint: str) -> SystemPromptBuilder:
        """添加一条约束。

        Args:
            constraint: 约束文本。

        Returns:
            ``self``,便于链式调用。
        """
        self.constraints.append(constraint)
        return self

    def add_rule(self, rule: str) -> SystemPromptBuilder:
        """添加一条额外规则。

        Args:
            rule: 规则文本。

        Returns:
            ``self``。
        """
        self.extra_rules.append(rule)
        return self

    def build(self) -> str:
        """构建最终的 system prompt 字符串。

        Returns:
            拼接好的 system prompt。
        """
        sections: list[str] = [f"# 角色\n{self.role}"]

        if self.constraints:
            lines = "\n".join(f"- {c}" for c in self.constraints)
            sections.append(f"# 约束\n{lines}")

        if self.output_format:
            sections.append(f"# 输出格式\n{self.output_format}")

        if self.extra_rules:
            lines = "\n".join(f"- {r}" for r in self.extra_rules)
            sections.append(f"# 附加规则\n{lines}")

        return "\n\n".join(sections)


def render_template(template: str, variables: dict[str, str]) -> str:
    """安全渲染字符串模板(使用 ``string.Template``)。

    Args:
        template: 含 ``$var`` 占位符的模板。
        variables: 变量字典。

    Returns:
        渲染后的字符串。

    Raises:
        KeyError: 模板中的变量未提供时。
    """
    # 先检查所有占位符是否都提供了
    needed = set(Template(template).get_identifiers())
    missing = needed - set(variables)
    if missing:
        raise KeyError(f"模板缺少变量: {missing}")
    return Template(template).substitute(variables)


def build_customer_service_prompt(product_name: str, language: str = "中文") -> str:
    """构建一个客服助手的 system prompt。

    Args:
        product_name: 产品名称。
        language: 回复语言。

    Returns:
        system prompt 字符串。
    """
    return (
        SystemPromptBuilder(role=f"你是 {product_name} 的客服助手,使用{language}回复。")
        .add_constraint("回答必须基于产品知识库,不得编造事实。")
        .add_constraint("若无法回答,明确告知并转人工。")
        .add_constraint("语气保持礼貌、专业、简洁。")
        .add_rule("遇到投诉先共情,再给出解决方案。")
        .build()
    )


def main() -> None:
    """演示系统提示构建。"""
    prompt = build_customer_service_prompt("云笔记 Pro")
    print(prompt)
    print("\n--- 模板渲染 ---")
    rendered = render_template(
        "请用 $tone 的语气介绍 $product。", {"tone": "专业", "product": "Agent"}
    )
    print(rendered)


if __name__ == "__main__":
    main()