AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


AI时代写Prompt应该用APPL:为Prompt工程打造的编程语言,来自清华姚班的博士
发布日期:2024-12-16 14:48:13 浏览次数: 1654 来源:AI修猫Prompt



在人工智能快速发展的今天,大语言模型(LLM)已经成为改变世界的重要力量。然而,如何高效地编写、管理和维护提示词(Prompt)仍然是一个巨大的挑战。传统的提示词工程往往依赖于手工编写和维护大量的文本模板,这不仅效率低下,而且难以进行版本控制和复用。

APPL(A Prompt Programming Language)的出现,为这个问题提供了一个优雅而强大的解决方案。作为连接程序和大语言模型的桥梁,APPL允许在Python函数中无缝嵌入提示词,同时也支持将提示词转换为结构化的程序代码。这种双向转换能力让开发者能够充分利用两个世界的优势:程序的精确控制和大语言模型的灵活创造力。

APPL是一个扩展了Python的提示词编程语言,它提供了一种自然、直观、便捷且高效的方式来在程序中使用大语言模型。作为一个专门面向Prompt工程师的工具,APPL不仅简化了提示词的编写和管理过程,还引入了一系列创新性的特性,从根本上改变了我们与大语言模型交互的方式。

APPL的第一作者:董宏华博士,本科毕业于清华大学交叉信息研究院(姚班),目前是多伦多大学在读博士。他带领团队开发了这个创新性的工具。作为专注于大语言模型应用的研究者,他们团队深入理解了当前Prompt工程师在日常工作中面临的挑战,并将这些洞察融入到APPL的设计中。他希望通过APPL,能够为广大的Prompt工程师提供一个更加高效、专业的开发工具,使他们能够更好地发挥创造力,构建更加复杂和强大的AI应用。

注意:本文以下示例代码由董宏华博士亲自修订。

资源

网页文档:https://appl-team.github.io/appl

上手教程:https://appl-team.github.io/appl/tutorials/ 

代码:https://github.com/appl-team/appl

论文:https://arxiv.org/abs/2406.13161

安装:

pip install -U applang

核心特性: 重塑提示词工程的范式

1. 提示词上下文系统的深度解析

APPL的核心创新在于其提示词上下文(Prompt Context)系统。这个系统不仅仅是简单的文本管理,而是一个复杂的状态管理机制:

  1. 上下文生命周期管理

  • new: 默认的模式,创建全新上下文,用于独立任务

  • same: 复用当前上下文,适合连续的提示词构建

  • copy: 创建上下文副本,用于并行处理

  • 创建阶段:每个APPL函数被调用时自动创建独立上下文

  • 传递阶段:支持三种上下文传递模式

  • 销毁阶段:追踪调用情况,方便用于后续调试

  • 提示词捕获机制

    • 表达式语句自动捕获:将Python表达式转换为提示词片段

    • 动态内容注入:支持变量插值和表达式计算

    • 条件性捕获:可根据运行时条件决定是否将内容加入提示词

  • 上下文状态追踪

    • 完整的调用链记录

    • 提示词构建过程的可视化

    • 运行时状态的监控

    示例代码展示提示词的简洁用法:

    from appl import ppl, gen

    @ppl(docstring_as="system")
    def simple_prompt(name: str):
    """This is a system prompt"""

    f"Hello, my name is {name}!"
    return gen()

    simple_prompt("APPL")的提示词如下

    system: This is a system prompt
    user: Hello, my name is APPL

    这被用于gen()函数来调用大语言模型。


    示例代码展示上下文管理的高级用法:

    import appl
    from appl import SystemMessage, convo, ppl, gen

    @ppl
    def complex_prompt(data: dict, mode: str = "default"):
    # 基础上下文设置
    SystemMessage("Processing data analysis request")

    # 条件性提示词构建
    if mode == "detailed":
    f"Analysis mode: Detailed examination"
    f"Required aspects: All data fields"
    else:
    f"Analysis mode: Quick overview"
    f"Required aspects: Key metrics"

    # 动态数据注入
    f"Input data summary:"
    for key, value in data.items():
    f"- {key}: {value}"

    # 使用Python控制流动态构建提示词
    if "errors" in data:
    f"Special attention: Error analysis required"
    f"Error details: {data['errors']}"

    return convo() # convo即conversation,表示当前的对话提示词

    print(complex_prompt({"name": "John", "age": 30, "errors": "Syntax error"}))

    得到的输出如下:

    system: Processing data analysis request
    user: Analysis mode: Quick overview
    Required aspects: Key metrics
    Input data summary:
    - name: John
    - age: 30
    - errors: Syntax error
    Special attention: Error analysis required
    Error details: Syntax error

    2. 并行化调度系统的技术实现

    APPL的并行化系统远比表面看到的要复杂。它实现了一个智能的任务调度器,能够自动识别和优化并行执行机会。在实际测试中,APPL展现出了显著的性能优势:

    • 在Chain-of-Thought with Self-Consistency(CoT-SC)任务中,实现了接近10倍的加速比

    • 在Skeleton-of-Thought(SoT)生成任务中,达到了2.79倍的加速效果

    • 在层次化摘要任务中,获得了3.07倍的性能提升

    这些性能提升主要得益于以下技术实现:

    1. 异步执行,在独立线程中运行大模型任务

    2. 自动检测大模型任务之间的数据依赖

    除此之外,APPL还提供了以下高级特性:

    • 线程池实现大模型调用数量的限流

    • 结果缓存

    • 失败恢复机制

    高级并行处理示例:

    @ppl
    def parallel_processing(documents: list[str]):
    SystemMessage("You are a document analysis tool.")

    # 并行执行每个文档的分析任务
    results = [analyze_document(doc) for doc in documents]

    # 结果汇总
    f"Analysis Summary:"
    for doc_id, result in enumerate(results):
    f"Document {doc_id}: {result}"
    print(convo()) # DEBUG,打印用于生成(gen)的对话提示词
    return gen()

    @ppl(ctx="copy")# 使用独立的上下文副本
    def analyze_document(doc: str):
    "Analyze the following document:"
    doc
    return gen()

    docs = ["first document ...", "second document ..."] # placeholder
    print(f"\n=== Analysis Summary ===\n{parallel_processing(docs)}")

    得到的输出如下:

    system: You are a document analysis tool.
    user: Analysis Summary:
    Document 0: This document ... # (分析结果)
    Document 1: This document ... # (分析结果)

    === Analysis Summary ===
    These documents ... # (汇总的分析结果)

    3. 工具调用系统的深度集成

    APPL的工具调用系统通过自动化的方式,将Python函数转换为大语言模型可以理解和使用的工具。这个过程包括:

    1. 函数签名分析

    • 自动提取Python函数参数和返回值类型

    • 解析函数文档字符串(docstring)

  • 工具Schema生成

    • 自动生成包含参数描述和约束条件的JSON Schema

    • 支持复杂的嵌套Pydantic结构

  • 调用结果处理

    • 将结果转化为函数调用,集成工具的运行

    • 可方便地并行运行多个工具执行

    这种自动化的工具集成机制大大简化了开发流程,使得开发者可以专注于业务逻辑的实现,而不需要手动处理繁琐的工具规范定义和参数转换。

    示例代码:

    # 常规的Python函数定义,参数类型可以是Pydantic模型
    def is_lucky(x: int) -> bool:
    """Determine whether the input number is a lucky number.

    Args:
    x (int): The input number to be checked.

    Returns:
    bool: True if the number is a lucky number, False otherwise.
    """

    return sympy.isprime(x + 3)


    @ppl
    def func(x):
    f"Is {x} a lucky number?"

    # 将 `is_lucky` 直接作为可用的工具,APPL会自动从函数签名和文档字符串中提取信息
    # 结果是一个AssistantMessage,可以直接加入到提示词中
    (actions := gen(tools=[is_lucky]))

    if actions.is_tool_call:# LLM的选择是调用工具
    # 运行工具,运行结果是ToolMessage的列表,可直接加入提示词中
    (results := actions.run_tool_calls())
    # results[0].content包含第一个工具调用的结果

    # 让LLM根据结果生成文本答案,选择不使用工具
    answer = gen(tools=[is_lucky], tool_choice="none")
    else:# LLM选择直接生成答案
    answer = actions.message

    return answer

    n = 2024
    ans = func(n)
    print("The answer is:", ans)

    包含工具调用的对话的示例如下:

    | Role | Message |
    | -------------- | ------------------------------------------------------------- |
    | User | Is 2024 a lucky number? |
    | Assistant| [ToolCall(id='call_...', name='is_lucky', args='{"x":2024}')] |
    | Tool(is_lucky) | True|

    输出示例如下:

    Yes, 2024 is a lucky number!

    4. Tree of Thought实现

    Tree of Thought(ToT)是一种强大的思维推理框架,它通过构建思维树并进行搜索来解决复杂问题。APPL为ToT提供了优雅而高效的实现支持,下面以24点游戏求解器为例展示APPL的强大能力:

    @ppl
    def propose(current_numbers: str):
    f"Propose at most {args.n_propose_sample} possible next steps without explanation"
    for example in PROPOSE_EXAMPLES:
    for k, v in example.items():
    display(k, v)
    f"Input: {current_numbers}"
    f"Possible next steps:"
    return gen()

    @ppl
    def evaluate(current_numbers: str):
    "Evaluate if given numbers can reach 24 (sure/likely/impossible)"
    for example in VALUE_EXAMPLES:
    for k, v in example.items():
    display(k, v)
    f"Input: {current_numbers}"
    "Thoughts:"
    return gen()

    @traceable
    def solve(input_numbers: str, steps: int = 3):
    current_candidates = [
    Game24Candidate(
    start_numbers=input_numbers,
    left_numbers=input_numbers,
    steps=[]
    )
    ]
    for _ in range(steps):
    # 生成可能的下一步
    new_candidates = get_all_proposals(current_candidates)

    # 评估每个候选解
    new_candidates = get_all_values(new_candidates)

    # 选择最佳候选解
    current_candidates = sorted(
    new_candidates,
    key=lambda x: x.value,
    reverse=True
    )[: args.n_select_sample]

    这个代码片段展示了APPL如何优雅地处理ToT的核心组件:

    1. 提案生成(propose):

    • 基于当前状态生成可能的下一步操作

    • 利用few-shot示例提升生成质量

    • 支持批量生成多个候选方案

  • 评估(evaluate):

    • 对每个候选解进行可行性评估

    • 使用分级评分机制(sure/likely/impossible)

    • 支持并行化评估提升效率

  • 搜索(solve):

    • 实现宽度优先搜索策略

    • 动态调整搜索深度

    • 通过评分进行最优解选择

    APPL的特性使得ToT实现具有以下优势:

    • 代码结构清晰,逻辑简洁

    • 提示词和代码互相解释

    • 自动并行化提升性能

    • 完整的执行追踪能力

    • 灵活的提示词管理

    在实际测试中,这个实现展现出了优秀的性能:

    • 并行运行使得解决单个24点问题的时间缩短为了原来的1/6。

    • 代码量显著减少 ,核心代码减少至120行左右。

    5. OPRO Prompt优化

    OPRO(Optimization of PROmpts)是谷歌DeepMind提出的一种创新的prompt优化技术,它通过迭代优化来提升prompt的效果,我之前有文章专门介绍过。

往期推荐

谷歌DeepMind重磅:提示工程师必须掌握OPRO,用LLM就能自动优化Prompt|ICLR2024

仅用十几行代码,APPL就能实现一个OPRO的简化版本,为类似算法提供了简洁而强大的实现支持:

@ppl
def optimize_prompt(question: str, prompt: str, output: str):
"I want to optimize the prompt for the question."
"The question is:"
question
"The current prompt is:"
prompt
"The output for the current prompt is:"
output
"The optimized prompt is:"
return gen()

@ppl
def evaluate_prompt(prompt: str):
prompt
return gen()

# 迭代优化过程
question = "Which number is larger, 9.11 or 9.9?"
prompt = "please think carefully."
for i in range(3):
# 评估当前prompt
output = evaluate_prompt(prompt)
# 生成优化后的prompt
prompt = optimize_prompt(question, prompt, output)

OPRO的工作原理:

  1. 初始prompt评估:

  • 测试初始prompt的效果

  • 分析输出结果的质量

  • 识别需要改进的方面

  • 优化策略生成:

    • 基于评估结果设计改进方案

    • 考虑多个优化维度

    • 生成新的prompt版本

  • 迭代优化过程:

    • 多轮评估和改进

    • 动态调整优化策略

    • 收敛到最优解

    APPL为OPRO提供的支持:

    • 提示词上下文的自动管理

    • 清晰的代码结构和流程控制

    • 方便的结果评估和分析

    • 完整的优化过程追踪

    • 优化后的prompt更简洁

    高级应用场景: 深入APPL的实战应用

    1. ReAct智能体实现

    APPL特别适合实现基于ReAct范式的智能体系统,它能够自然地结合思考(Thought)、行动(Action)和观察(Observation):

    @ppl
    def react_agent(instruction: str, max_steps: int = 5):
    SystemMessage("你是一个能够思考和使用工具的AI助手。")
    f"用户指令: {instruction}\n"

    tools = [finish_task]

    for step in range(max_steps):
    # 生成思考过程
    f"思考: {gen(tools=tools, tool_choice='none')}"

    # 选择并执行工具
    (actions := gen(tools=tools))

    # 运行并将结果加入提示词
    (results := actions.run_tool_calls())

    # 根据results判断是否完成任务,如果完成则退出循环
    ...

    "生成最终答案:"
    return gen()

    这个实现展示了APPL如何优雅地处理复杂的交互流程,包括:

    • 自然语言思考过程

    • 工具选择和调用

    • 结果分析和决策

    2. 高级代码解析

    APPL可以方便地将整个文件夹内的代码放入提示词中,用于代码审查、讨论和调试。这种高级代码解析功能可以极大地提升开发效率,特别适用于代码审查、问题排查和团队协作:

    以下代码展示了如何将文件目录结构与目录中代码以XML的格式放入提示词中,比如将APPL的examples作为source folder后,里面的所有代码都会进入提示词中,然后就可以跟这些示例进行交流。

    @ppl
    def chat(source_folder: str, ext: str = ".py"):
    with Tagged("directory", attrs={"name": source_folder}):
    "The source code is organized as follows:"
    sd.seedir(
    source_folder,
    style="spaces",
    printout=False,
    exclude_folders=["__pycache__"],
    )
    with Tagged("source"):
    "The contents of the source code are as follows:"
    # 遍历目录下的所有文件
    for name in glob.glob(
    os.path.join(source_folder, "**", f"*{ext}"), recursive=True
    ):
    with Tagged("file", attrs={"name": name}):
    "```python"
    with open(name, "r", encoding="utf-8") as f:
    f.read()# 读取文件内容并放入提示词中
    "```"
    "Now begin the chat about the project:\n"
    print(f"num_tokens: {get_num_tokens(str(convo()))}")

    console = Console()
    while True:
    (query := prompt("User: ")) # 用户输入对话
    if query.startswith("exit"):
    break
    console.print(make_panel(query, title="User"))
    logger.info(f"User: {query}")
    with AIRole():
    (res := str(gen(stream=True).streaming(title="Assistant")))
    logger.info(f"Assistant: {res}")


    技术评价:APPL的创新与影响

    APPL作为一个开创性的提示词编程工具,展现出了显著的技术优势和广阔的应用前景:

    1. 技术创新

    1. 架构设计:

    • 创新的提示词上下文系统

    • 高效的并行化调度机制

    • 灵活的工具集成框架

  • 开发体验:

    • 自然的编程范式

    • 简洁的库调用设计

    • 强大的调试能力

  • 性能优化:

    • 智能的资源管理

    • 高效的并行处理

    • 优秀的扩展性

    2. 实践价值

    1. 开发效率:

    • 显著减少代码量

    • 加快开发速度

    • 降低维护成本

  • 应用场景:

    • 支持复杂AI系统开发

    • 适应多样化的任务需求

    • 便于集成现有系统

  • 生态潜力:

    • 活跃的社区支持

    • 丰富的工具生态

    • 良好的扩展性

    结语: 拥抱提示词工程的新范式

    APPL代表了提示词工程的未来发展方向。它通过创新的技术架构和丰富的功能特性,为AI应用开发提供了一个强大而灵活的工具。对于Prompt工程师来说,掌握APPL不仅能够提高开发效率,还能够创造出更加强大和可维护的AI应用。

    随着APPL的持续发展和完善,我们可以期待看到更多创新性的应用出现,推动整个AI领域向前发展。现在正是开始学习和使用APPL的最佳时机,让我们一起探索这个充满可能的新领域。如果APPL对您有帮助,请点赞在看和转发。以下文章对您可能也有帮助:



53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询