Saltar al contenido principal

Outputs estructurados

¿Qué resolver?

Forzar la salida de LLM en formato JSON y es el esquema especificado

Soluciones antiguas

En el prompt, solicite que el LLM produzca el formato JSON y el nombre y el tipo de cada campo, por ejemplo,

output in JSON object with follow fileds:
- name: string
- age: number
- isFemale: boolean

LangChain tiene un analizador que puede ayudarle a generar palabras.

Pregunta 1

Sin embargo, hay una probabilidad de que LLM produzca un formato no JSON, o que el campo no se espera.

Soluciones posteriores

La API de OpenAI introduce el modo 'json _ object' que puede obligar a los LLM a devolver el formato JSON.

Pregunta 2

Los campos devueltos por el LLM pueden no ser los esperados.

Las últimas soluciones

El esquema de salida estructurada de OpenAI puede pasar un esquema JSON explícito en el campo de la API para que el LLM pueda producir el formato especificado.

response_format: { "type": "json_schema", "json_schema": … , "strict": true }

Puede especificar el formato en json _ schema, como:

{
type: "json_schema",
json_schema: {
name: "math_response",
schema: {
type: "object",
properties: {
steps: {
type: "array",
items: {
type: "object",
properties: {
explanation: { type: "string" },
output: { type: "string" }
},
required: ["explanation", "output"],
additionalProperties: false
}
},
final_answer: { type: "string" }
},
required: ["steps", "final_answer"],
additionalProperties: false
},
strict: true
}
}

En Node.js puedes usarlo de manera más sencilla:

Definir el esquema JSON

import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const Step = z.object({
explanation: z.string(),
output: z.string(),
});

const MathResponse = z.object({
steps: z.array(Step),
final_answer: z.string(),
});

Coloque en el campo response _ format

const completion = await openai.beta.chat.completions.parse({
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "You are a helpful math tutor. Guide the user through the solution step by step." },
{ role: "user", content: "how can I solve 8x + 7 = -23" },
],
response_format: zodResponseFormat(MathResponse, "math_response"),
});

Muy conveniente.

    • Cómo usarlo en LangChain * *
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

export async function main() {
const CalendarEvent = z.object({
name: z.string(),
date: z.string(),
participants: z.array(z.string()),
});

const model = new ChatOpenAI({
model: "gpt-4o-mini",
// 在这里添加
modelKwargs: {
response_format: zodResponseFormat(CalendarEvent, "event"),
},
});
const messages = [
new SystemMessage("Extract the event information."),
new HumanMessage("我和小明参加婚礼"),
];
const parser = new StringOutputParser();

const chain = model.pipe(parser);
const resp = await chain.invoke(messages);
console.log(resp);
}

Referendum

官网