a step · two agents in parallel, one contract, a scorer
const researchStep = createStep({
  id: 'research',
  execute: async ({ inputData }) => {
    // two sources at once: the docs agent from the last slide,
    // and a coding agent reading the repository, minutes
    const [docs, analysis] = await Promise.all([
      docsAgent.generate(inputData.body, {
        structuredOutput: { schema: docsAnswerSchema },
      }),
      taskRock8CloudAgent({
        service: 'demo', type: 'research', prompt: inputData.body,
      }),
    ])
    // this step gathers. The next one decides.
    return { ...inputData, docs: docs.object, analysis: analysis.text }
  },
  // online: a scorer on a quarter of real runs
  scorers: {
    grounded: { scorer: isGrounded,
      sampling: { type: 'ratio', rate: 0.25 } },
  },
})
a scorer · is the research grounded?
export const isGrounded = createScorer({
  id: 'is-grounded',
  description:
    'Do both sources point at something real: ' +
    'a docs page, and a file in the repository?',
}).generateScore(({ run }) => {
  const { docs, analysis } = run.output
  const checks = [
    docs.cited.length > 0,
    // a file path in the analysis text
    /[\w\/-]+\.\w+/.test(analysis),
  ]
  const passed = checks.filter(Boolean).length
  return passed / checks.length
})