You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Outlines库Prompt装饰器类型提示问题:Pyright误判如何解决?

问题:Outlines库Prompt装饰器的类型推断问题

Outlines库的Prompt类实现了__call__方法,调用时会返回字符串;而prompt装饰器直接返回Prompt实例,而非常见的嵌套函数结构。当按如下方式使用时:

@prompt
def my_system_prompt():
    """This is system prompt."""

system_prompt = my_system_prompt()

Pyright会将system_prompt的类型推断为str,如果开发者期望保留Prompt实例而非渲染后的字符串,就会引发类型匹配问题。

解决方案

1. 直接保留Prompt实例(推荐)

如果不需要立即渲染模板,不要调用装饰后的函数,直接赋值即可:

@prompt
def my_system_prompt():
    """This is system prompt."""

# 直接保留Prompt实例,跳过调用步骤
system_prompt = my_system_prompt

此时Pyright会正确推断system_prompt的类型为Prompt,后续可按需调用它生成字符串。

2. 修改Prompt类设计(需修改库代码)

如果需要调用实例但仍保留Prompt类型,可以调整__call__方法的职责,新增专门的渲染方法:

from dataclasses import dataclass
import inspect
from typing import List, Callable, cast

# 假设render是库中已存在的模板渲染函数
def render(template: str, **kwargs) -> str:
    return template.format(**kwargs)

@dataclass
class Prompt:
    template: str
    signature: inspect.Signature

    def __post_init__(self):
        self.parameters: List[str] = list(self.signature.parameters.keys())
        self.bound_args = None

    def __call__(self, *args, **kwargs) -> "Prompt":
        """绑定参数并返回自身,不直接渲染"""
        self.bound_args = self.signature.bind(*args, **kwargs)
        self.bound_args.apply_defaults()
        return self

    def render(self) -> str:
        """专门的渲染方法,返回字符串结果"""
        if not self.bound_args:
            self.bound_args = self.signature.bind()
            self.bound_args.apply_defaults()
        return render(self.template, **self.bound_args.arguments)

    def __str__(self):
        return self.template

def prompt(fn: Callable) -> Prompt:
    signature = inspect.signature(fn)
    docstring = fn.__doc__
    if docstring is None:
        raise TypeError("Could not find a template in the function's docstring.")
    template = cast(str, docstring)
    return Prompt(template, signature)

使用方式:

@prompt
def my_system_prompt(name: str):
    """Hello, {name}!"""

# 调用后仍得到Prompt实例
system_prompt = my_system_prompt("Alice")
# 需要字符串时调用render方法
prompt_str = system_prompt.render()

3. 显式类型注解(仅类型检查层面生效)

如果必须调用且无法修改库代码,可通过显式类型注解强制指定变量类型,但需注意运行时实际值仍为字符串:

from typing import cast

@prompt
def my_system_prompt():
    """This is system prompt."""

# 强制指定类型(仅用于类型检查,运行时system_prompt仍是字符串)
system_prompt = cast(Prompt, my_system_prompt())

⚠️ 注意:这种方法仅能骗过类型检查器,若后续调用Prompt类的方法会触发运行时错误,仅适用于特殊场景。

内容的提问来源于stack exchange,提问作者Vikash Balasubramanian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:33:27