Inicio / Artículos / Agente de informes ejecutivos al jefe de estado mayor: arquitectura en capas a escala empresarial

Agente de informes ejecutivos al jefe de estado mayor: arquitectura en capas a escala empresarial

Guía práctica para el Agente de Informes Ejecutivos del Jefe de Estado Mayor: arquitectura en capas a escala empresarial: contratos, verificaciones y espacios para código adicional para los equipos que implementan este patrón.

4574 palabras

Esta guía reconstruye el proceso desde las materias primas hasta un sistema funcional para: Chief of Staff Executive Briefing Agent: arquitectura en capas a escala empresarial para la generación automática de inteligencia. El enfoque está en pasos operativos, verificaciones explícitas y código que se puede incorporar directamente a un repositorio sin necesidad de adivinar su propósito. En la etapa de visión general, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto el camino óptimo como el de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

Visión general del diseño de la solución

Al trabajar en la fase de descripción general del diseño de la solución, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando falla un paso, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Haga una verificación después de los pasos costosos. El sistema de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

Capa de base: Consolidación de datos empresariales regulada

Al trabajar en la etapa empresarial regulada de la capa Foundation, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Trate esta etapa como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las comprobaciones de éxito y evite completaciones parciales silenciosas. Haga una verificación después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

Capa de datos: El motor de inteligencia operativa optimizado para el consumo de API

Al trabajar en la capa de datos durante la fase operativa, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando se pasa de entornos de demostración a entornos compartidos. Haga un punto de control después de los pasos costosos. La reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior. Al trabajar en la capa de datos durante la fase operativa, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

     --Accounts Table - Primary Business Entity

CREATE TABLE [aieo].[Accounts] (

    [Id] INT IDENTITY(1,1) PRIMARY KEY,

    [TPID] BIGINT NOT NULL,

    [AccountName] NVARCHAR(255) NOT NULL,

    [AccountNumber] NVARCHAR(50),

    [SearchTokens] NVARCHAR(500),

    [Segment] NVARCHAR(100),

    [Industry] NVARCHAR(100),

    [ACR_FY25] DECIMAL(15,2),

    [RevenueRank] INT,

    [CreatedDate] DATETIME2 DEFAULT GETUTCDATE(),

    [LastSync] DATETIME2,

    [IsActive] BIT DEFAULT 1

);



CREATE CLUSTERED INDEX IX_Accounts_TPID ON [aieo].[Accounts]([TPID]);

CREATE NONCLUSTERED INDEX IX_Accounts_Name ON [aieo].[Accounts](
-- Revenue Table - Historical and Forecast Data

CREATE TABLE [aieo].[Revenue] (

    [TPID] BIGINT,

    [FiscalYear] NVARCHAR(10),

    [RevenueType] NVARCHAR(20),

    [Amount] DECIMAL(15,2),

    [LastUpdated] DATETIME2

);

CREATE INDEX IX_Revenue_TPID_FY ON [aieo].[Revenue]([TPID], [FiscalYear]);
-- AI Usage Table - Product Adoption Metrics

CREATE TABLE [aieo].[AIUsage] (

    [TPID] BIGINT,

    [ProductCategory] NVARCHAR(50),

    [UsageLevel] NVARCHAR(20),

    [SeatCount] INT,

    [AdoptionRate] DECIMAL(5,2),

    [LastUpdated] DATETIME2

);

CREATE INDEX IX_AIUsage_TPID_Product ON [aieo].[AIUsage]([TPID], [ProductCategory]);
--Account Search Procedure - Revenue-Prioritized Discovery

CREATE OR ALTER PROCEDURE [aieo].[SearchAccounts]

    @searchTerm NVARCHAR(255),

    @top INT = 5

AS

BEGIN

    SET NOCOUNT ON;



    DECLARE @likeTerm NVARCHAR(257) = '%' + REPLACE(REPLACE(@searchTerm, '[', '[[]'), '%', '[%]') + '%'



    SELECT TOP (@top)

        a.TPID,

        a.AccountName,

        a.AccountNumber,

        ISNULL(acr.ACR_YTD, 0) as ACR_YTD

    FROM [aieo].[Accounts] a

    LEFT JOIN [aieo].[ACR] acr ON a.TPID = acr.TPID

    WHERE

        a.AccountName LIKE @likeTerm

        OR CAST(a.TPID AS NVARCHAR) = @searchTerm

        OR a.AccountNumber LIKE @likeTerm

    ORDER BY

        ISNULL(acr.ACR_YTD, 0) DESC,

        a.AccountName ASC

    FOR JSON PATH;

END;
--Account Details Retrieval Procedure - Comprehensive Intelligence Aggregation

CREATE PROCEDURE [aieo].[GetAccountDetails]

(@TPID int)

AS

BEGIN

    SET NOCOUNT ON;

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;



    SELECT TOP 1

        JSON_QUERY(ap.[AccountProfile]) AS [Account],

        JSON_QUERY(ai.[AIUsage]) AS [AI],

        JSON_QUERY(acr.[Data]) AS [ACR],

        deal.[Deals.AgreementValue],

        deal.[Deals.DealType],

        deal.[Deals.Term],

        deal.[Deals.Remaining],

        deal.[Deals.EndDate],

        ecif.[ECIF.Committed],

        aco.[ACO.IncrementalRevenue],

        aco.[ACO.Discount],

        aco.[ACO.ACO],

        JSON_QUERY(bot.[Data]) AS [BoT],

        JSON_QUERY(inv.[Data]) AS [Investments],

        JSON_QUERY(rev.[Data]) AS [Revenue]

    FROM [dbo].[vw_Customer] P

    OUTER APPLY (

        SELECT TOP 1

            a.[TPID],

            a.[CRMAccountName] AS [AccountName],

            a.[Segment],

            a.[Industry],

            a.[EOU],

            a.[OU],

            LOWER(TRIM(c.[Value])) AS [ATU_Manager.Alias],

            aau.[Mail] AS [ATU_Manager.Email],

            [dbo].[RemoveJobTitle](aau.[DisplayName]) AS [ATU_Manager.DisplayName],

            NULLIF(TRIM(aau.[BusinessPhone]), '') AS [ATU_Manager.PhoneNumber],

            JSON_QUERY([am].[Data]) AS [AM],

            JSON_QUERY([atum].[Data]) AS [ATUM]

        FROM [dbo].[vw_Customer] A

        OUTER APPLY STRING_SPLIT(a.[AM], ',', 1) C

        LEFT JOIN [cm].[vw_AAD_User] AAU ON LOWER(TRIM(C.[Value])) = LOWER(AAU.[UserPrincipalName])

        WHERE A.TPID = P.TPID

    ) ap

    WHERE P.TPID = @TPID;

END;
--Template Management Procedure - Role-Based Access Control

CREATE OR ALTER PROCEDURE [aieo].[GetBriefingTemplate]

(

    @UserAlias NVARCHAR(200),

    @BriefingType NVARCHAR(200)

)

AS

BEGIN

    SET @UserAlias = IIF(CHARINDEX('@', @UserAlias) > 0,

                        LEFT(@UserAlias, CHARINDEX('@', @UserAlias) - 1),

                        @UserAlias)



    SELECT DISTINCT

        [BriefingTemplateId],[TemplateDescription],[BriefingType],

        [UserAlias],FullName,[Filename],[FileType],[PreviewFilename]

    FROM [hr].[DimPerson] p

    INNER JOIN [aieo].[ExecutiveOfficeMember] eom ON eom.[PersonnelNumber] = p.[PersonnelNumber]

    INNER JOIN [aieo].[ExecutiveOffice] o ON o.[ExecutiveOfficeId] = eom.[ExecutiveOfficeId]

    INNER JOIN [aieo].[BriefingTemplate] bt ON bt.[ExecutiveOfficeId] = o.[ExecutiveOfficeId]



    UNION



    SELECT DISTINCT

        [BriefingTemplateId],[TemplateDescription],[BriefingType],

        p.EmailName As UserAlias,p.FullName,[Filename],[FileType],[PreviewFilename]

    FROM [aieo].[BriefingTemplate] bt

    CROSS JOIN [hr].[DimPerson] p

    WHERE bt.[UserAlias] = 'ALL' AND p.EmailName = @UserAlias

        AND bt.BriefingType = @BriefingType;

END;
GRANT EXECUTE ON SCHEMA::[aieo] TO [service_identity];
 - No direct table access permitted

Capa de servicio: orquestación sin estado y límite de ejecución

La etapa de orquestación sin estado de la capa de servicio funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando falla un paso, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y dificultan la reanudación después de interrupciones.

from pydantic import BaseModel
from typing import Optional
class BriefingRequest(BaseModel):
account_name_or_tpid: str
meeting_datetime: Optional[str] = None
meeting_objective: Optional[str] = None
ms_attendees: Optional[str] = None
template_type: Optional[str] = None

Capa de experiencia: motor de inteligencia conversacional Copilot Studio

La capa de experiencia en la etapa de Copilot Studio funciona mejor cuando se trata como una superficie medible. Capture una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace las completaciones parciales silenciosas. Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación posterior.

kind: AdaptiveDialog

inputs:

  - kind: AutomaticTaskInput

    propertyName: Account_Name_or_TPID

    name: Account Name or TPID

    description: The account/customer TPID (unique identifier) or name

    shouldPromptUser: true



modelDescription: Create briefing document to prepare for meeting with customer

beginDialog:

  kind: OnRecognizedIntent

  intent:

    displayName: Topic for creating briefing document to prepare for meeting with customer

    triggerQueries:

      - Generate a briefing document for account Accenture

      - I need a briefing for Amazon

      - Create briefing for Apple

      - I have a meeting with JPMorgan Chase at 4PM
- kind: SetVariable

  id: setVariable_IsNumeric

  variable: Topic.IsNumeric

  value: =IsNumeric(Topic.UserInput)



- kind: ConditionGroup

  id: conditionGroup_InputType

  conditions:

    - id: condition_IsTPID

      condition: =Topic.IsNumeric

      actions:

        - kind: SetVariable

          variable: Topic.Account_TPID

          value: =Topic.UserInput
- kind: HttpRequestAction

  id: httpRequest_SearchAccounts

  displayName: Search Accounts by Name

  url: =Global.ApiBaseUrl & "/api/mssales/search/" & EncodeUrl(Topic.UserInput)

  headers:

    Ocp-Apim-Subscription-Key: =Global.ApiKey

  response: Topic.SearchResults

  responseSchema:

    kind: Record

    properties:

      accounts:

        type:

          kind: Table

          properties:

            account_name: String

            tpid: String

      total_count: Number
- kind: AdaptiveCardPrompt

  id: adaptiveCard_SelectAccount

  card: "=Concatenate('{

    \"$schema\":\"https://adaptivecards.io/schemas/adaptive-card.json\",

    \"type\":\"AdaptiveCard\",\"version\":\"1.5\",

    \"body\":[

      {\"type\":\"TextBlock\",\"text\":\"Multiple accounts found\",\"weight\":\"Bolder\"},

      {\"type\":\"Input.ChoiceSet\",\"id\":\"selectedAccount\",\"isRequired\":true,

       \"choices\":',

       JSON(ForAll(Topic.SearchResults.accounts,

         {title: Concatenate(account_name, \" (TPID: \", tpid, \")\"), value: tpid})),

       '}],

    \"actions\":[{\"type\":\"Action.Submit\",\"title\":\"Continue\"}]

  }')"
- kind: HttpRequestAction

  id: httpRequest_GetUserTemplates

  url: =Global.ApiBaseUrl & "/api/briefings/templates?user_alias=" &

       EncodeUrl(System.User.PrincipalName) & "&briefing_type=Customer"

  headers:

    Ocp-Apim-Subscription-Key: =Global.ApiKey

  response: Topic.UserTemplates
- kind: AdaptiveCardPrompt

  id: adaptiveCard_MeetingDetails

  card: "=Concatenate('{

    \"$schema\":\"https://adaptivecards.io/schemas/adaptive-card.json\",

    \"type\":\"AdaptiveCard\",\"version\":\"1.5\",

    \"body\":[

      {\"type\":\"TextBlock\",\"text\":\"Create Executive Briefing Document\",

       \"weight\":\"Bolder\",\"size\":\"Large\",\"color\":\"Accent\"},

      {\"type\":\"Input.Date\",\"id\":\"meetingDate\",\"isRequired\":true,

       \"label\":\"Meeting Date\"},

      {\"type\":\"Input.Time\",\"id\":\"meetingTime\",\"value\":\"09:00\"},

      {\"type\":\"Input.Text\",\"id\":\"msAttendees\",\"isVisible\":false,

       \"label\":\"Microsoft Attendees\"}

    ],

    \"actions\":[

      {\"type\":\"Action.ToggleVisibility\",\"title\":\"Additional Options ▼\",

       \"targetElements\":[\"msAttendees\"]},

      {\"type\":\"Action.Submit\",\"title\":\"Generate Briefing\"}

    ]

  }')"
// Ephemeral Logic App Security Pattern
const createSearchLogicApp = async (userAlias, searchQuery) => {
const logicAppName = `Researcher-${userAlias}`;
// Create Logic App with SAS trigger
const logicApp = await armClient.logicApps.createOrUpdate({
resourceGroupName: 'Azure_OpenAI',
workflowName: logicAppName,
definition: buildResearchWorkflow(userAlias)
});
// Execute search via SAS URL
const searchResults = await triggerLogicApp(logicApp.triggerUrl, searchQuery);
// Immediate cleanup for security
await armClient.logicApps.delete(logicAppName);
return searchResults;
};
# Logic App Parallel Execute Pattern

HTTP_Trigger_SAS_Secured:

  Email_Branch:

    - Get_Emails: Office365_Connector.Mail (top=250)



  Teams_Branch_Parallel:

    - Get_Teams_Chats_Page1: Teams_Connector.Chats (top=50)

    - Get_Teams_Chats_Page2: Teams_Connector.Chats (skip=50, top=50)

    - For_Each_Chat:

        concurrency: 10

        actions:

          - Get_Chat_Messages: Teams_Connector.Messages (top=50)

          - Append_Chat_Data: Variable_Accumulation



  Response_Assembly:

    - Combine: Email_Results + Teams_Results + Metadata

    - Return: JSON_Structured_Response
// Per-User Connection Provisioning

const provisionUserConnections = async (userAlias) => {

    const connections = [

        {

            name: `office365-${userAlias}`,

            api: '/providers/Microsoft.PowerApps/apis/shared_office365',

            scopes: ['Mail.ReadWrite']

        },

        {

            name: `teams-${userAlias}`,

            api: '/providers/Microsoft.PowerApps/apis/shared_teams',

            scopes: ['Chat.Read']

        }

    ];



    for (const conn of connections) {

        await armClient.connections.createOrUpdate({

            resourceGroupName: 'Azure_OpenAI',

            connectionName: conn.name,

            properties: {

                displayName: conn.name,

                api: { id: conn.api },

                parameterValues: {}

            }

        });

    }



    return generateConsentUrls(connections);

};
# Organizational Intelligence Synthesis

async def synthesize_organizational_context(filtered_data, account_context):

    synthesis_prompt = """

    Analyze the following organizational communications for executive briefing preparation:



    Account Context: {account_name}

    Email Communications: {email_count} relevant messages

    Teams Discussions: {chat_count} relevant conversations

    Generate executive intelligence focusing on:
    Financial performance, earnings trends, and capital allocation signals.
    Corporate strategy, market positioning, and competitive landscape.
    AI strategy, digital transformation initiatives, and cloud ecosystem alignment.
    Recent material developments (≤ 90 days) with actionable insights for executive engagement.

    Format as structured JSON with executive_summary, stakeholder_analysis, recent_activities, and recommended_actions.

    """



    response = await azure_openai_client.chat.completions.create(

        model="gpt-4-1106-preview",

        messages=[{

            "role": "system",

            "content": "You are an executive intelligence analyst."

        }, {

            "role": "user",

            "content": synthesis_prompt.format(**filtered_data, **account_context)

        }],

        temperature=0.1,

        max_tokens=2000

    )



    return parse_structured_intelligence(response.choices[0].message.content)
# Enhanced Copilot Studio Parallel Execution

- kind: ParallelExecution

  id: parallelExecution_ComprehensiveIntelligence

  branches:

    - account_data:

        kind: HttpRequestAction

        url: =Global.ApiBaseUrl & "/api/accounts/" & Topic.Account_TPID

    - organizational_intelligence:

        kind: HttpRequestAction

        url: =Global.ApiBaseUrl & "/api/search?q=" & EncodeUrl(Topic.Account_Name) & "&alias=" & System.User.PrincipalName

        requestTimeoutInMilliseconds: 60000

        continueOnError: true

    - market_intelligence:

        kind: HttpRequestAction

        url: =Global.FoundryBaseUrl & "/bingnews/api/AgentFunction"



- kind: SetVariable

  id: setVariable_CombinedIntelligence

  variable: Topic.BriefingContext

  value: ={

    account_details: Topic.AccountData,

    organizational_context: Topic.OrganizationalIntelligence,

    market_insights: Topic.MarketIntelligence

  }
// Enterprise Governance and Cleanup

const implementGovernanceControls = async () => {

    // Automated stale connection cleanup

    const staleThreshold = 80; // days

    const allConnections = await listManagedConnections();



    const staleConnections = allConnections.filter(connection => {

        const lastUsed = parseISO(connection.properties.lastConnection);

        const daysSinceUse = differenceInDays(new Date(), lastUsed);

        return daysSinceUse > staleThreshold;

    });



    // Compliance audit logging

    for (const connection of staleConnections) {

        await auditLogger.log({

            action: 'CONNECTION_CLEANUP',

            userAlias: connection.userAlias,

            reason: 'AUTOMATED_GOVERNANCE',

            retentionPolicy: `${staleThreshold}_DAYS_INACTIVE`,

            timestamp: new Date().toISOString()

        });



        await deleteUserResources(connection.userAlias);

    }

};
// Fault-Tolerant Execution Pattern

const executeOrganizationalIntelligence = async (searchQuery, userAlias) => {

    const executionTimeout = 60000; // 60 second maximum

    const fallbackResponse = { summary: "Organizational context unavailable", status: "fallback" };



    try {

        // Health check before expensive operations

        const connectionsHealthy = await verifyConnectionHealth(userAlias);

        if (!connectionsHealthy) {

            return fallbackResponse;

        }



        // Execute with timeout boundary

        const intelligencePromise = gatherOrganizationalIntelligence(searchQuery, userAlias);

        const timeoutPromise = new Promise((_, reject) =>

            setTimeout(() => reject(new Error('TIMEOUT')), executionTimeout)

        );



        return await Promise.race([intelligencePromise, timeoutPromise]);



    } catch (error) {

        // Graceful degradation logging

        await logger.warn(`M365 Researcher fallback: ${error.message}`, {

            userAlias,

            searchQuery,

            fallbackMode: true

        });



        return fallbackResponse;

    }

};
- kind: HttpRequestAction

  id: p4tceX

  method: Post

  url: =Global.ApiBaseUrl & "/api/briefings/" & Topic.templateId & "/accounts/" & Topic.Account_TPID

  body:

    kind: JsonRequestContent

    content: "={

      user_alias: Topic.SenderEmail,

      MeetingDateTime: Topic.MeetingDateTime,

      msAttendees: Topic.msAttendees,

      FoundryResponse: Topic.FoundryResponse

    }"

  requestTimeoutInMilliseconds: 60000

  response: Topic.BriefingDocument
- kind: InvokeConnectorAction

  id: invokeConnectorAction_YKkMK4

  input:

    binding:

      dataset: https://microsoft.sharepoint.com/teams/MCAPSAIIncubationHub

      folderPath: /Shared Documents/General/AI Prototypes & Solutions/AI Executive Office Use Cases/Published Cust Template/

      name: =Topic.CustomFilename

      file: =Global.File
- kind: SetVariable

  id: setVariable_CustomFilename

  variable: Topic.CustomFilename

  value: =Concatenate(

    Substitute(Topic.Account_Name, " ", "_"), "_",

    Topic.ExecutiveName, "_Brief_",

    Text(Topic.meetingDate, "yyyy-MM-dd"), ".docx"

  )
- kind: ConditionGroup

  id: conditionGroup_CheckBriefingError

  conditions:

    - condition: =!IsBlank(Topic.BriefingDocument.error) && Topic.BriefingDocument.error.error_code = "TEMPLATE_ACCESS_DENIED"

      actions:

        - kind: AdaptiveCardPrompt

          card: ={

            "$schema":"https://adaptivecards.io/schemas/adaptive-card.json",

            "type":"AdaptiveCard","version":"1.5",

            "body":[{

              "type":"Container","style":"warning",

              "items":[{

                "type":"TextBlock","text":"Template Access Required",

                "weight":"Bolder","color":"Attention"

              },{

                "type":"TextBlock","wrap":true,

                "text": Topic.BriefingDocument.error.user_message

              }]

            }]

          }
- kind: ConditionGroup

  id: conditionGroup_ValidateInputs

  conditions:

    - condition: =Topic.meetingDate < Today()

      actions:

        - kind: SendActivity

          activity: The meeting date cannot be in the past. Please start over and enter a future date.

        - kind: EndConversation
- kind: SetVariable

  id: setVariable_ClearUserInput

  variable: Topic.UserInput

  value: =Blank()



- kind: SetVariable

  id: setVariable_ClearAccountDetails

  variable: Topic.AccountDetails

  value: =Blank()



- kind: SetVariable

  id: setVariable_ClearFoundryResponse

  variable: Topic.FoundryResponse

  value: =Blank()



- kind: SetVariable

  id: setVariable_ClearBriefingDocument

  variable: Topic.BriefingDocument

  value: =Blank()
# Environment-aware authentication pattern

def get_credential():

    if is_azure_environment():

        return ManagedIdentityCredential(client_id=os.getenv('AZURE_CLIENT_ID'))

    else:

        return AzureCliCredential()
Structured exception hierarchy

class AIExecutiveOfficeError(Exception):

    def __init__(self, message: str, error_code: str = None, details: dict = None):

        self.message = message

        self.error_code = error_code or self.__class__.__name__

        self.details = details or {}

        self.timestamp = datetime.utcnow()

Marco de evaluación y validación de calidad

El marco de evaluación y la fase de calidad funcionan mejor cuando se consideran como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo en tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la versión de demostración a entornos compartidos. Mantenga el estado del grafo simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso. El marco de evaluación y la fase de calidad funcionan mejor cuando se consideran como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el camino de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

Siguientes pasos: Migración al Microsoft Agent Framework (MAF)

Para los siguientes pasos de migración a la fase de pruebas, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el error debe indicar una única responsabilidad y no un proceso complicado. Incluya la aprobación humana en aquellos casos que impliquen gastos o cambios en los datos de producción. La configuración en tiempo de compilación no equivale a la completitud del proceso empresarial.

Conclusión

En la fase de Conclusión, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Trate esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace las completaciones parciales silenciosas. Incluya la aprobación humana en aquellos casos que impliquen gastos o cambios en los datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial.

Lista de verificación operativa

La fase de la lista de verificación operativa funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance.

Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema.

Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso tras las interrupciones.

Añada una prueba de funcionamiento básica que ejerza la ruta crítica en los procesos de integración continua utilizando fixtures, y no APIs pagadas en tiempo real, siempre que lo permitan los presupuestos.

Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso tras las interrupciones.

Antes de promocionar la pila tecnológica, congele las versiones, capture una transcripción de referencia para la ruta crítica y confirme los pasos para revertir cambios. Los entornos compartidos necesitan límites de velocidad, verificaciones de asignación y un responsable claro para la rotación de credenciales secretas. Prefiera una fiabilidad sencilla a demostraciones ingeniosas pero puntuales.

Nota de lote para 8b1aa812f08c: mantener las claves del proveedor fuera del repositorio, establecer un límite para los tokens por sesión y almacenar las transcripciones junto a los archivos de evaluación para que los cambios posteriores en el modelo sigan siendo comparables.

La nota de refuerzo de etapa 0 funciona mejor cuando se trata como una superficie medible. Capture una transcripción de referencia, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo en tokens o consultas junto a los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas al pasar del entorno de demostración a entornos compartidos.

Detalle de refuerzo 0/857: mida el tiempo de ejecución, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la fase 1 de las notas de fortalecimiento, defina los insumos, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras realizadas posteriormente.

Detalle de fortalecimiento 1/857: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la fase 2 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Trate esta fase como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las comprobaciones de éxito y rechace las completaciones parciales silenciosas.

Detalle de fortalecimiento 2/857: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

La fase 3 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción de referencia, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar que los operadores puedan auditar sin tener que leer todo el sistema.

Detalle de fortalecimiento 3/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la fase 4 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado.

Detalle de fortalecimiento 4/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la fase 5 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la fase de demostración a entornos compartidos.

Detalle de fortalecimiento 5/857: mida el tiempo empleado, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener la modificación basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.

La fase 6 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el camino de recuperación. Los intentos repetidos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

Detalle de fortalecimiento 6/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

En la fase 7 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Trate esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace las completaciones parciales silenciosas.

Detalle de fortalecimiento 7/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la etapa 8 de las notas de fortalecimiento, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código.

Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema.

Detalle de fortalecimiento 8/857: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de criterios en lugar de en observaciones anecdóticas.

La etapa 9 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance.

Prefiera unidades pequeñas y verificables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una sola responsabilidad y no a un proceso complicado.

Detalle de refuerzo 9/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la etapa 10 de las notas de refuerzo, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Registre los tiempos y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos.

Detalle de refuerzo 10/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la fase 11 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código.

Documente tanto el camino óptimo como el de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

El detalle de fortalecimiento 11/857: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de anécdotas.

La fase 12 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta fase como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las verificaciones de éxito y rechace las completaciones parciales silenciosas.

Detalle de fortalecimiento 12/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la fase 13 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar que los operadores puedan auditar sin tener que leer todo el sistema.

Detalle de fortalecimiento 13/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la fase 14 de las notas de fortalecimiento, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.

Detalle de fortalecimiento 14/857: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener la modificación basándose en un conjunto fijo de preguntas en lugar de anécdotas.

La fase 15 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de la demostración a entornos compartidos.

Detalle de fortalecimiento 15/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la fase 16 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

Detalle de fortalecimiento 16/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la fase 17 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Trate esta fase como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las comprobaciones de éxito y rechace las completaciones parciales silenciosas.

Detalle de fortalecimiento 17/857: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

La fase 18 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción de referencia, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar que los operadores puedan auditar sin tener que leer todo el sistema.

Detalle de fortalecimiento 18/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la fase 19 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado.

Detalle de fortalecimiento 19/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la fase 20 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la fase de demostración a entornos compartidos.

Detalle de fortalecimiento 20/857: mida el tiempo empleado, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener la modificación basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.

La fase 21 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente junto con ello el camino óptimo y el camino de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son algo que se añade posteriormente.

Detalle de reforzamiento 21/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

En la fase 22 del proceso de reforzamiento, defina las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea a partir de un punto de control conocido sin tener que adivinar el estado oculto. Trate esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace las completaciones parciales silenciosas.

Detalle de reforzamiento 22/857: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Lecturas relacionadas