跳到内容

响应模型

在 Instructor 中定义 LLM 输出模式是通过我们的 InstructMacro 宏完成的,该宏从您的 Rust Struct 生成底层的 JSON Schema。我们开箱即用地支持各种不同类型,例如 Enums、Vecs 和 Option 类型,在此处阅读更多关于如何使用它们的信息。

幕后发生了什么?

在运行时,Rust 将您的结构体编译成内存块,每个字段都有特定的偏移量。

访问字段涉及使用这些偏移量,类似于通过索引访问数组元素。这种方法确保了结构体是高效的,并且与手动内存管理技术相比没有额外的运行时开销。

struct Example {
    a: u32,
    b: u64,
    c: u8,
}

这意味着我们丢失了您在代码中使用的类型和字段的大量信息。当我们使用 InstructMacro 时,我们在底层重写您的结构体,以暴露一个包含结构体信息的 get_info() 方法。

 #[derive(InstructMacro, Debug)]
#[allow(dead_code)]
#[description("This is a struct")]
struct TestStruct {
    #[description(
        "This is a sample example \
        that spans across \
        three lines"
    )]
    pub field1: String,
    #[description("This is a test field")]
    pub field2: str,
}

我们在底层添加了这段代码(您可以使用 cargo-expand 命令 cargo expand <file name> 查看所有展开的代码)。

impl instruct_macros_types::InstructMacro for TestStruct {
    fn get_info() -> instruct_macros_types::InstructMacroResult {
        let mut parameters = Vec::new();
        parameters
            .push(
                Parameter::Field(ParameterInfo {
                    name: "field1".to_string(),
                    r#type: "String".to_string(),
                    comment: "This is a sample example that spans across three lines"
                        .to_string(),
                    is_optional: false,
                    is_list: false,
                }),
            );
        parameters
            .push(
                Parameter::Field(ParameterInfo {
                    name: "field2".to_string(),
                    r#type: "str".to_string(),
                    comment: "This is a test field".to_string(),
                    is_optional: false,
                    is_list: false,
                }),
            );
        instruct_macros_types::InstructMacroResult::Struct(StructInfo {
            name: "TestStruct".to_string(),
            description: "This is a struct".to_string(),
            parameters,
            is_optional: false,
            is_list: false,
        })
    }
    fn validate(&self) -> Result<(), String> {
        Ok(())
    }
}