Skip to content
Embabel 文档版本 0.3.0-SNAPSHOT 源快照 2d81c035 更新于 2026-09-29

12 · 类型(Types)

核心类型(Core Types)

LlmOptions

LlmOptions 类用于指定使用哪个 LLM 及其超参数。 它定义在 embabel-common 项目中,提供流式 API 来进行 LLM 配置:

java
// 用模型与温度创建 LlmOptions
var options = LlmOptions
        .withModel(OpenAiModels.GPT_4O_MINI)
        .withTemperature(0.8);

// 不同任务使用不同超参数
var analyticalOptions = LlmOptions
        .withModel(OpenAiModels.GPT_4O_MINI)
        .withTemperature(0.2)
        .withTopP(0.9);

重要方法:

  • withModel(String):指定模型名称;
  • withRole(String):指定模型角色。该角色必须是配置中通过 embabel.models.llms 定义过的;
  • withTemperature(Double):设置创造性/随机性(0.0 ~ 1.0);
  • withTopP(Double):设置 nucleus 采样参数;
  • withTopK(Integer):设置 top-K 采样参数;
  • withPersona(String):添加一条 system message 人设。

LlmOptions 是可反序列化的,因此你可以在 application.yml 等应用配置文件中设置 LlmOptions 类型的属性。 这是把模型乃至超参数外部化的一种强力做法。

PromptRunner

用户应用中的所有 LLM 调用都应该通过 PromptRunner 接口进行。 一个 PromptRunner 一旦创建,就可以用同一套 LLM、超参数、工具组与 PromptContributor 运行多个提示词。

获取 PromptRunner

通过流式 API 从 OperationContext 获取 PromptRunner:

java
@Action
public Story createStory(UserInput input, OperationContext context) {
    // 用默认 LLM 获取 PromptRunner
    var runner = context.ai().withDefaultLlm();

    // 用指定的 LLM 选项获取 PromptRunner
    var customRunner = context.ai().withLlm(
            LlmOptions.withModel(OpenAiModels.GPT_4O_MINI)
                    .withTemperature(0.8)
    );

    return customRunner.createObject("Write a story about: " + input.getContent(), Story.class);
}

PromptRunner 方法

核心:创建对象

  • createObject(String, Class):从提示词创建类型化对象,失败则抛异常。异常会触发重试;若反复重试失败,则触发重规划。
  • createObjectIfPossible(String, Class):尝试创建对象,失败时返回 null。这可能引起重规划。
  • generateText(String):生成简单文本响应。

通常你会想用某个 createObject 方法,以确保响应被正确类型化。

工具与上下文管理

  • withToolGroup(String):为 LLM 访问添加工具组;
  • withToolObject(Object):添加带 @Tool 方法的领域对象;
  • withPromptContributor(PromptContributor):添加上下文贡献器;
  • withImage(AgentImage):为支持视觉的 LLM 在提示词中加入一张图片;
  • withImages(AgentImage...):在提示词中加入多张图片。

LLM 配置

  • withLlm(LlmOptions):使用特定的 LLM 配置;
  • withGenerateExamples(Boolean):控制示例生成。

返回特定类型

  • creating(Class):进入 Creating 流式 API,用于返回特定类型。

例如:

java
var story = context.ai()
        .withDefaultLlm()
        .withToolGroup(CoreToolGroups.WEB)
        .creating(Story.class)
        .fromPrompt("Create a story about: " + input.getContent());

这么做的主要原因是为 few-shot 提示添加强类型示例。例如:

java
var story = context.ai()
        .withDefaultLlm()
        .withToolGroup(CoreToolGroups.WEB)
        .creating(Story.class)
        .withExample("A children's story", new Story("Once upon a time...")) // ①
        .fromPrompt("Create a story about: " + input.getContent());

① 示例会以 JSON 格式被包含进提示词,用以引导 LLM。

处理图片

java
var image = AgentImage.fromFile(imageFile);

var answer = context.ai()
        .withLlm(AnthropicModels.CLAUDE_35_HAIKU) // ①
        .withImage(image)                          // ②
        .generateText("What is in this image?");

① 需要支持视觉的模型:使用 Claude 3.x、GPT-4 Vision 或其它多模态 LLM。 ② 添加图片:图片会随文本提示词一起发给 LLM。可以多次调用以添加多张图片。

处理文档

java
var documentPath = java.nio.file.Paths.get("reports/quarterly-report.pdf");

var message = userMessage()
        .document(documentPath)
        .build();

var answer = context.ai()
        .withDefaultLlm() // ①
        .withMessage(message)
        .generateText("Summarize this report");

① 需要支持文档的模型:默认或配置的 LLM 必须能消费文档输入。文档支持取决于所选模型与提供方。

gemini-autoconfigure 提供方使用的是 Google 的 OpenAI 兼容端点,它支持文本与图片输入,但不支持文档文件部分。 要处理 Gemini 的文档输入,请使用原生的 Google GenAI 提供方。

multimodal(text, file) 与 multimodal(text, path) 是图片的快捷方式。 对文档文件或路径,请使用 multimodal(text).document(fileOrPath).build() 或 AgentDocument.fromFile(file)。

高级特性

  • rendering(String):使用 Jinja 模板生成提示词(返回 Rendering 接口);
  • withTool(Subagent.ofClass(MyAgent.class).consuming(MyInput.class)):启用向其它 Agent 的移交(handoff);
  • evaluateCondition(String, String):评估布尔条件。

校验(Validation)

Embabel 支持在领域对象上使用 JSR-380(Bean Validation)注解。 当通过 PromptRunner.createObject 或 createObjectIfPossible 创建对象时,反序列化后会自动执行校验。 如果校验失败,Embabel 会透明地重试该 LLM 调用以获取合法对象,并把校验错误描述给 LLM,帮助它修正响应。

如果第二次校验仍失败,会抛出 InvalidLlmReturnTypeException。 若不捕获,它将触发重规划。你也可以选择在发起 LLM 调用的动作方法内部捕获它,并在自己的代码里做相应处理。

注解用法简单示例:

java
public class User {

    @NotNull(message = "Name cannot be null")
    private String name;

    @AssertTrue(message = "Working must be true")
    private boolean working;

    @Size(min = 10, max = 200, message
            = "About Me must be between 10 and 200 characters")
    private String aboutMe;

    @Min(value = 18, message = "Age should not be less than 18")
    @Max(value = 150, message = "Age should not be greater than 150")
    private int age;

    @Email(message = "Email should be valid")
    private String email;

    // 标准的 setter 与 getter
}

你也可以使用自定义注解,其 validator 会由 Spring 注入。例如:

java
@Target({ElementType.FIELD, ElementType.PARAMETER}) // ①
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PalindromeValidator.class)
public @interface MustBePalindrome {
    String message() default "Must be a palindrome";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

public class Palindromic {
    @MustBePalindrome // ②
    private String eats;

    public Palindromic(String eats) {
        this.eats = eats;
    }

    public String getEats() {
        return eats;
    }
}

@Component // ③
public class PalindromeValidator implements ConstraintValidator<MustBePalindrome, String> {

    private final Ai ai; // ④

    public PalindromeValidator(Ai ai) {
        this.ai = ai;
    }

    @Override
    public boolean isValid(String field, ConstraintValidatorContext context) {
        if (field == null) {
            return false;
        }
        return field.equals(new StringBuilder(field).reverse().toString());
    }
}

注记:

  • ① 定义自定义注解;
  • ② 把注解应用到字段上;
  • ③ 把 validator 实现为 Spring 组件 —— 注意 @Component 注解;
  • ④ Spring 会把依赖注入进 validator,例如本例中的 Ai 实例。

于是我们就得到了带完整 Spring 依赖注入支持的、标准的 JSR-380 校验。

AgentImage

表示一张用于支持视觉的 LLM 的图片。

工厂方法:

  • AgentImage.fromFile(File):从文件加载(会依据常见扩展名自动识别 MIME 类型);
  • AgentImage.fromPath(Path):从路径加载(自动识别 MIME 类型);
  • AgentImage.create(String, byte[]):用显式 MIME 类型与字节数组创建;
  • AgentImage.fromBytes(String, byte[]):用文件名与字节创建(自动识别 MIME 类型)。

如果对某个受支持的图片格式自动识别失败,请改用 AgentImage.create() 并显式指定 MIME 类型。

AgentDocument

表示一份用于支持文档的 LLM 的文档。

工厂方法:

  • AgentDocument.fromFile(File):从文件加载(会依据常见扩展名自动识别 MIME 类型);
  • AgentDocument.fromPath(Path):从路径加载(自动识别 MIME 类型);
  • AgentDocument.create(String, byte[], String?):用显式 MIME 类型、字节数组以及可选文件名创建;
  • AgentDocument.fromBytes(String, byte[]):用文件名与字节创建(自动识别 MIME 类型)。

Embabel 能按 MIME 类型识别 PDF、CSV、Microsoft Office 文档(.doc、.docx、.xlsx)以及 OpenDocument 文件(.odt、.ods、.odp)。 提供方的支持情况随模型与适配器而异,请确认所选 LLM 能消费你要发送的文档格式。

如果对某个受支持的文档格式自动识别失败,请改用 AgentDocument.create() 并显式指定 MIME 类型。

示例:

java
var documentPath = java.nio.file.Paths.get("reports/quarterly-report.pdf");

var message = userMessage()
        .document(documentPath)
        .build();

var answer = context.ai()
        .withDefaultLlm()
        .withMessage(message)
        .generateText("Summarize this report");

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。