游乐游手机版
首页/AI热点日报/热点详情

前OpenAI研究科学家开源提示工程库ell重新定义提示工程

类型:热点整理2026-05-30
在之前的文章里,我们聊了不少关于提示工程的前沿技术和工具。它们都指向同一个方向:提示工程不只是人机对话的语言艺术,更是一个需要持续迭代、系统化的软件工程。最近,OpenAI前研究科学家William开源了一个号称面向未来的提示工程库——ell[1]。这个库把提示当作函数来对待,并配了一套强大的工具来

在之前的文章里,我们聊了不少关于提示工程的前沿技术和工具。它们都指向同一个方向:提示工程不只是人机对话的语言艺术,更是一个需要持续迭代、系统化的软件工程。最近,OpenAI前研究科学家William开源了一个号称面向未来的提示工程库——ell[1]。这个库把提示当作函数来对待,并配了一套强大的工具来帮你管理和优化提示。它背后的一些设计理念,很值得琢磨。

提示是程序,而不是字符串

传统做法里,提示通常被当成简单的字符串。但ell彻底碘伏了这个看法——它把提示看作程序。这样一来,你可以把提示封装成独立的子程序,也就是所谓的语言模型程序(Language Model Program, LMP)。这些LMP是彻底的封装函数,可以生成字符串提示或者消息列表,然后发给各种多模态语言模型。

先看一个传统的API调用示例,然后用ell实现同样的功能。下面是OpenAI Chat Completion API的常规写法:

import openai

openai.api_key = "your-api-key-here"

messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Say hello to Sam Altman!"}
]

response = openai.ChatCompletion.create(
    model="gpt-4o",
    messages=messages
)

print(response['choices'][0]['message']['content'])

现在看看ell怎么做:

import ell

@ell.simple(model="gpt-4o")
def hello(name: str):
    """You are a helpful assistant."""  # 系统提示
    return f"Say hello to {name}!"  # 用户提示

greeting = hello("Sam Altman")
print(greeting)

ell鼓励你把提示定义为功能单元,从而简化流程。在这里,hello函数通过文档字符串定义系统提示,通过返回字符串定义用户提示。调用者只需调用函数,不用手动构建消息。

在此基础上,还能进一步改进:

import ell
import random

def get_random_adjective():
    adjectives = ["enthusiastic", "cheerful", "warm", "friendly"]
    return random.choice(adjectives)

@ell.simple(model="gpt-4o")
def hello(name: str):
    """You are a helpful assistant."""
    adjective = get_random_adjective()
    return f"Say a {adjective} hello to {name}!"

greeting = hello("Sam Altman")
print(greeting)

这个hello LMP依赖get_random_adjective函数。每次调用都会生成不同的形容词,创建动态、多样的提示。很明显,ell让提示变得更可读、可维护、可重用。

提示工程是一个优化过程

提示工程的过程,本质和机器学习里的优化类似:需要反复迭代。既然LMP就是函数,ell提供了丰富的工具来支撑这种迭代。

ell通过静态和动态分析,实现了提示的自动版本控制和序列化,并自动生成提交消息到本地存储。这就像机器学习训练中的检查点,但不需要特殊的IDE或编辑器——用常规Python代码就行。

import ell

ell.init(store='./logdir')  # 版本控制你的LMP和它们的调用

# 定义你的LMP
hello("strawberry")  # LMP的源代码和调用被保存到存储中

同时,ell提供了一个名为Ell Studio的本地开源工具,用于提示版本控制、监控和可视化。通过Ell Studio,你可以把提示优化过程科学化,在问题出现之前就捕捉到回归。

优雅实现测试时计算

从演示到实际应用,往往需要多次调用语言模型。这不是简单的字符串拼接,而是复杂的编程过程。ell通过强制功能分解问题,让测试时计算变得既可读又模块化。

import ell

@ell.simple(model="gpt-4o-mini", temperature=1.0, n=10)
def write_ten_drafts(idea: str):
    """You are an adept story writer. The story should only be 3 paragraphs"""
    return f"Write a story about {idea}."

@ell.simple(model="gpt-4o", temperature=0.1)
def choose_the_best_draft(drafts: List[str]):
    """You are an expert fiction editor."""
    return f"Choose the best draft from the following list: {'\n'.join(drafts)}."

drafts = write_ten_drafts(idea)
best_draft = choose_the_best_draft(drafts)  # 从10个草稿中选择最佳草稿

测试时计算(Test-Time Computation)是机器学习和深度学习中的一个概念,指在模型推理阶段(测试时)进行额外计算或处理,以提高模型性能或适应性。这种方法常用于解决训练数据和测试数据之间存在差异的问题,或者在不重新训练模型的情况下提高泛化能力。核心思路是不重新训练模型,而是在实际使用时进行额外处理,以提升表现。类似人类在应用所学知识时,会根据具体情况灵活变通,而不是僵化执行。

每次调用语言模型都很重要

每次LLM调用都值得跟踪分析。实践中,这些调用用于微调、蒸馏、k-shot提示、从人类反馈进行强化学习等等。一个好的提示工程系统应该把这些作为一等公民来捕捉。

除了存储每个LMP的源代码,ell还能选择性地本地保存每次调用语言模型的记录。这让你能够生成调用数据集、比较不同版本的LMP输出、充分利用提示工程的所有工件。

需要时复杂,不需要时简单

使用语言模型很多时候只是传递字符串,但偶尔需要更复杂的输出。ell提供了@ell.simple@ell.complex装饰器,分别用于生成简单字符串输出和复杂的消息对象响应。

import ell

@ell.tool()
def scrape_website(url: str):
    return requests.get(url).text

@ell.complex(model="gpt-5-omni", tools=[scrape_website])
def get_news_story(topic: str):
    return [
        ell.system("""Use the web to find a news story about the topic"""),
        ell.user(f"Find a news story about {topic}.")
    ]

message_response = get_news_story("stock market")
if message_response.tool_calls:
    for tool_call in message_response.tool_calls:
        # 处理工具调用
        pass
if message_response.text:
    print(message_response.text)
if message_response.audio:
    # message_response.play_audio() 支持多模态输出
    pass

多模态是一等公民

LLM能够处理和生成各种类型的内容,包括文本、图像、音频和视频。使用这些数据类型进行提示工程,应该像处理文本一样简单。

from PIL import Image
import ell

@ell.simple(model="gpt-4o", temperature=0.1)
def describe_activity(image: Image.Image):
    return [
        ell.system("You are VisionGPT. Answer <5 words all lower case."),
        ell.user(["Describe what the person in the image is doing:", image])
    ]

# 从摄像头捕捉图像
describe_activity(capture_webcam_image())  # 输出: "they are holding a book"

ell支持多模态输入和输出的丰富类型转换。你可以在LMP返回的Message对象中内联使用PIL图像、音频和其他多模态输入。

提示工程库不干扰你的工作流程

ell被设计为一个轻量级且不干扰的库。它不要求你改变编码风格或使用特殊的编辑器。

你可以在你的IDE里继续用常规Python代码定义和修改提示,同时利用ell的功能来可视化和分析你的提示。你也可以从langchain逐步迁移到ell,一次一个函数。

结语

ell通过把提示视为函数,并提供一系列强大的工具,重新定义了提示工程。它不仅简化了提示的创建和管理过程,还让提示优化变得科学化和系统化。无论你是提示工程的新手还是老手,ell都能为你提供实实在在的支持。

来源:https://www.53ai.com/news/tishicijiqiao/2024091246095.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。