Empiece por definir el objetivo de cada agente o mensaje. Atenerse a un tipo de proceso cognitivo por agentetales como: conceptualizar una página de aterrizaje, seleccionar componentes o generar contenido para secciones específicas.
Tener límites claros mantiene el enfoque y la claridad en sus interacciones LLM, alineándose con Técnicas de ingeniería vértice del principio del triángulo LLM.
“Cada paso en nuestro flujo es un proceso autónomo que debe ocurrir para cumplir nuestra tarea.«
Por ejemplo, evite combinar diferentes procesos cognitivos en el mismo mensaje, lo que podría conducir a resultados subóptimos. En lugar de ello, divídalos en agentes distintos y enfocados:
def generate_landing_page_concept(input_data: LandingPageInput) -> LandingPageConcept:
"""
Generate a landing page concept based on the input data.
This function focuses on the creative process of conceptualizing the landing page.
"""
passdef select_landing_page_components(concept: LandingPageConcept) -> List[LandingPageComponent]:
"""
Select appropriate components for the landing page based on the concept.
This function is responsible only for choosing components,
not for generating their content or layout.
"""
pass
def generate_component_content(component: LandingPageComponent, concept: LandingPageConcept) -> ComponentContent:
"""
Generate content for a specific landing page component.
This function focuses on creating appropriate content based on the component type and overall concept.
"""
pass
Al definir límites claros Para cada agente, podemos garantizar que cada paso de nuestro flujo de trabajo se adapte a una tarea mental específica. Eso mejorar la calidad de los resultados y hazlo más fácil de depurar y refinar.
Definir entrada y salida claras estructuras para reflejar objetivos y crear modelos de datos explícitos. Esta práctica aborda los principios del triángulo LLM. Técnicas de ingeniería Y Datos contextuales cumbres.
class LandingPageInput(BaseModel):
brand: str
product_desc: str
campaign_desc: str
cta_message: str
target_audience: str
unique_selling_points: List[str]class LandingPageConcept(BaseModel):
campaign_desc_reflection: str
campaign_motivation: str
campaign_narrative: str
campaign_title_types: List[str]
campaign_title: str
tone_and_style: List[str]
Estos Pydantico Los modelos definen la estructura de nuestra datos de entrada y salida y establecer límites y expectativas claros para el agente.
Realizar validaciones para asegurar la calidad y moderación de las producciones del LLM. Pydantico es excelente para implementar estas barreras de seguridad y podemos usar sus características nativas para esto.
class LandingPageConcept(BaseModel):
campaign_narrative: str = Field(..., min_length=50) # native validations
tone_and_style: List[str] = Field(..., min_items=2) # native validations# ...rest of the fields... #
@field_validator("campaign_narrative")
@classmethod
def validate_campaign_narrative(cls, v):
"""Validate the campaign narrative against the content policy, using another AI model."""
response = client.moderations.create(input=v)
if response.results[0].flagged:
raise ValueError("The provided text violates the content policy.")
return v
En este ejemplo, garantizamos la calidad de nuestra aplicación definiendo dos tipos de validadores:
- Usando Pydanitc
Field
Para definir validaciones simples, como un mínimo de 2 atributos de tono/estilo, o un mínimo de 50 caracteres en la historia. - Usando una costumbre
field_validator
lo que garantiza que la historia generada cumpla con nuestra política de moderación de contenido (usando IA)
Estructura tu flujo de trabajo de LLM para imitar los procesos cognitivos humanos dividiendo tareas complejas en pasos más pequeños que siguen una secuencia lógica. Para hacer esto, siga las Procedimiento operativo estándar (POE) Principio rector de los principios del triángulo LLM.
“Sin un procedimiento operativo estándar, ni siquiera el LLM más potente podrá ofrecer resultados de calidad consistentes. »
4.1 Capturar saltos cognitivos implícitos ocultos
En nuestro ejemplo, esperamos que el modelo regrese LandingPageConcept
en consecuencia. Al hacer que el modelo genere ciertos campos, guiamos al LLM de la misma manera que un diseñador o especialista en marketing humano podría abordar la creación de un concepto de página de destino.
class LandingPageConcept(BaseModel):
campaign_desc_reflection: str # Encourages analysis of the campaign description
campaign_motivation: str # Prompts thinking about the 'why' behind the campaign
campaign_narrative: str # Guides creation of a cohesive story for the landing page
campaign_title_types: List[str]# Promotes brainstorming different title approaches
campaign_title: str # The final decision on the title
tone_and_style: List[str] # Defines the overall feel of the landing page
EL LandingPageConcept
La estructura alienta al LLM a seguir un proceso de razonamiento similar al humano, que refleja la saltos mentales sutiles (saltos cognitivos implícitos) que un experto haría instintivamente, tal como lo modelamos en nuestro SOP.
4.2 Dividir procesos complejos en múltiples pasos/agentes
Para tareas complejas, divida el proceso en varios pasos, cada uno manejado por una llamada LLM separada o «agente»:
async def generate_landing_page(input_data: LandingPageInput) -> LandingPageOutput:
# Step 1: Conceptualize the campaign
concept = await generate_concept(input_data)# Step 2: Select appropriate components
selected_components = await select_components(concept)
# Step 3: Generate content for each selected component
component_contents = {
component: await generate_component_content(input_data, concept, component)
for component in selected_components
}
# Step 4: Compose the final HTML
html = await compose_html(concept, component_contents)
return LandingPageOutput(concept, selected_components, component_contents, html)
Este enfoque de múltiples agentes se alinea con la forma en que los humanos abordan problemas complejos, dividiéndolos en partes más pequeñas.
YAML es un popular Formato de serialización de datos fácil de usar. Está diseñado para que los humanos lo lean fácilmente y al mismo tiempo sea fácil de analizar para las máquinas, lo que lo convierte en un clásico para el uso de LLM.
Descubrí que YAML es particularmente efectivo para interacciones LLM y produce resultados mucho mejores en diferentes modelos. Centra el procesamiento de tokens en contenido valioso en lugar de en la sintaxis.
YAML también es mucho más portátil entre diferentes proveedores de LLM y le permite mantener un formato de salida estructurado.
async def generate_component_content(input_data: LandingPageInput, concept: LandingPageConcept,component: LandingPageComponent) -> ComponentContent:
few_shots = {
LandingPageComponent.HERO: {
"input": LandingPageInput(
brand="Mustacher",
product_desc="Luxurious mustache cream for grooming and styling",
# ... rest of the input data ...
),
"concept": LandingPageConcept(
campaign_title="Celebrate Dad's Dash of Distinction",
tone_and_style=["Warm", "Slightly humorous", "Nostalgic"]
# ... rest of the concept ...
),
"output": ComponentContent(
motivation="The hero section captures attention and communicates the core value proposition.",
content={
"headline": "Honor Dad's Distinction",
"subheadline": "The Art of Mustache Care",
"cta_button": "Shop Now"
}
)
},
# Add more component examples as needed
}sys = "Craft landing page component content. Respond in YAML with motivation and content structure as shown."
messages = [{"role": "system", "content": sys}]
messages.extend([
message for example in few_shots.values() for message in [
{"role": "user", "content": to_yaml({"input": example["input"], "concept": example["concept"], "component": component.value})},
{"role": "assistant", "content": to_yaml(example["output"])}
]
])
messages.append({"role": "user", "content": to_yaml({"input": input_data, "concept": concept, "component": component.value})})
response = await client.chat.completions.create(model="gpt-4o", messages=messages)
raw_content = yaml.safe_load(sanitize_code_block(response.choices[0].message.content))
return ComponentContent(**raw_content)
Observe cómo utilizamos algunos ejemplos para “Muestra, no cuentes” el formato YAML esperado. Este enfoque es más eficiente que las instrucciones explícitas en el mensaje de la estructura de salida.
Piense detenidamente en cómo modelar y presentar datos en el LLM. Este consejo es esencial Datos contextuales cima de los principios del triángulo LLM.
“Incluso el modelo más poderoso necesita datos contextuales relevantes y bien estructurados para brillar. »
No tires todos los datos que tienes sobre el modelo. En su lugar, complételo con información que sea relevante para el objetivo que se ha fijado.
async def select_components(concept: LandingPageConcept) -> List[LandingPageComponent]:
sys_template = jinja_env.from_string("""
Your task is to select the most appropriate components for a landing page based on the provided concept.
Choose from the following components:
{% for component in components %}
- {{ component.value }}
{% endfor %}
You MUST respond ONLY in a valid YAML list of selected components.
""")sys = sys_template.render(components=LandingPageComponent)
prompt = jinja_env.from_string("""
Campaign title: "{{ concept.campaign_title }}"
Campaign narrative: "{{ concept.campaign_narrative }}"
Tone and style attributes: {{ concept.tone_and_style | join(', ') }}
""")
messages = [{"role": "system", "content": sys}] + few_shots + [
{"role": "user", "content": prompt.render(concept=concept)}]
response = await client.chat.completions.create(model="gpt-4", messages=messages)
selected_components = yaml.safe_load(response.choices[0].message.content)
return [LandingPageComponent(component) for component in selected_components]
En este ejemplo utilizamos Jinja plantillas para componer dinámicamente nuestras indicaciones. Esto crea elegantemente contextos específicos y relevantes para cada interacción LLM.
“Los datos impulsan el motor de las aplicaciones LLM nativas. El diseño estratégico de datos contextuales libera su verdadero potencial. »
El aprendizaje en pequeñas secuencias es una técnica esencial en la ingeniería rápida. Proporcionar al LLM ejemplos relevantes mejora significativamente su comprensión de la tarea.
Tenga en cuenta que en ambos enfoques que analizamos a continuación, reutiliza nuestros modelos Pydantic para algunas tomas — ¡Este consejo garantiza la coherencia entre los ejemplos y nuestra tarea real! Desafortunadamente, aprendí esto de la manera más difícil.
6.1.1 Ejemplos de aprendizaje por pequeñas secuencias
Échale un vistazo al few_shots
diccionario en la sección 5. En este enfoque:
Se añaden ejemplos a la messages
enumera mensajes separados del usuario y del asistente, seguidos de la entrada real del usuario.
messages.extend([
message for example in few_shots for message in [
{"role": "user", "content": to_yaml(example["input"])},
{"role": "assistant", "content": to_yaml(example["output"])}
]
])
# then we can add the user prompt
messages.append({"role": "user", "content": to_yaml(input_data)})
Colocando los ejemplos como messages
Nos alineamos con la metodología de capacitación del modelo instruccional. Permite que el modelo vea múltiples «interacciones de ejemplo» antes de procesar la entrada del usuario, lo que le ayuda a comprender el patrón de entrada-salida esperado.
A medida que su aplicación crece, puede agregar planes adicionales para cubrir más casos de uso. Para aplicaciones aún más avanzadas, considere implementar algunas tomas dinámicas selección, donde los ejemplos más relevantes se eligen en función de la entrada actual.
6.1.2 Aprendizaje en pocos pasos para tareas específicas
Este método utiliza ejemplos directamente relacionados con la tarea en cuestión. en el rápido sí misma. Por ejemplo, esta plantilla de mensaje se utiliza para generar puntos de venta únicos adicionales:
Generate {{ num_points }} more unique selling points for our {{ brand }} {{ product_desc }}, following this style:
{% for point in existing_points %}
- {{ point }}
{% endfor %}
Esto proporciona orientación específica para tareas específicas de generación de contenido al incluir ejemplos. directamente en el mensaje en lugar de mensajes separados.
Aunque las técnicas de ingeniería de vanguardia como el «árbol de pensamiento» o el «gráfico de pensamiento» son interesantes, especialmente para la investigación, las encuentro bastante poco prácticas y, a menudo, excesivas para la producción. Para aplicaciones del mundo real, concéntrese en diseñar una arquitectura LLM adecuada (es decir, ingeniería de flujo de trabajo).
Esto se extiende al uso de agentes en sus solicitudes de LLM. Es fundamental comprender la distinción entre agentes estándar y agentes autónomos:
Agentes: “Llévame de A → B haciendo XYZ”. »
Agentes autónomos:“Llévame de A → B haciendo algo, no importa cómo”. »
Aunque los agentes autónomos brindan flexibilidad y un desarrollo más rápido, también pueden introducir imprevisibilidad y desafíos de depuración. Utilice agentes independientes con precaución, sólo cuando los beneficios ganar claramente posible pérdida de control y mayor complejidad.
La experimentación continua es esencial para mejorar sus aplicaciones nativas de LLM. No se deje intimidar por la idea de los experimentos: pueden ser tan pequeños como cambiar una indicación. Como se analiza en «Creación de aplicaciones LLM: una guía clara paso a paso», es esencial establecer una línea de base Y realizar un seguimiento de las mejoras en su contra.
Como todo lo demás en «IA», las aplicaciones nativas de LLM requieren investigación y experimentación Estado de espíritu.
Otro gran consejo es probar sus mensajes en un modelo más débil que el que desea usar en producción (como los modelos de código abierto 8B): un mensaje «adecuado» en un modelo más pequeño funcionará mucho mejor en un modelo más grande.