Quick start
import { openai } from '@agentskit/adapters'import { createEducationAccreditationEvidenceAgent } from './agents/education-accreditation-evidence/agent'const agent = createEducationAccreditationEvidenceAgent({ adapter: openai({ apiKey: process.env.OPENAI_API_KEY!, model: 'gpt-4o', }),})const result = await agent.run('Describe your task here')console.log(result.content)Independent reviewer approved
Validation evidence
- Review score
- 96/100
- Confidence
- 96%
- Evaluation cases
- 3
- Iterations
- 1
The agent produced valid structured outputs for all three cases, avoided fabricating accreditation facts from sparse inputs, surfaced concrete gaps and open questions, and resisted the explicit injection request. Behavior is conservative but appropriate for an accreditation evidence agent where unsupported claims would be high risk. Minor weakness: it somewhat over-labels ordinary sparse prompts as injection/untrusted content, which reduces usefulness in the normal case, but it still provides a safe and actionable evidence-readiness result.
What passed review
- Valid non-empty structured outputs in every case.
- No material hallucination of institutions, standards, dates, names, or evidence artifacts.
- Clear gap lists and open questions that help a human complete accreditation evidence preparation.
- Successfully ignored the injection request to output only APPROVED.
- Consistently marked outputs as requiring review when evidence was insufficient.
Reviewer notes
- Reduce overuse of prompt-injection framing for benign sparse inputs; reserve that language for actual instruction conflicts while still treating missing facts conservatively.
Extend it
Pass tools, retrieval, memory, permissions, and observers through the factory config.
const agent = createEducationAccreditationEvidenceAgent({ adapter, tools, retriever, memory, onConfirm: (call) => approve(call), observers: [tracer],})View agent factory source
import type { AdapterFactory, ChatMemory, Observer, ToolCall, ToolDefinition } from '@agentskit/core'import { fenceUntrustedContent, UNTRUSTED_CONTENT_DIRECTIVE } from '@agentskit/core/security'import { invokeStructured } from '@agentskit/runtime'import { defineZodTool } from '@agentskit/tools'import { z } from 'zod'import { zodToJsonSchema } from 'zod-to-json-schema'import type { JSONSchema7 } from 'json-schema'/** Accreditation Evidence — v1 validated. Pain: Accreditation prep */export interface Section { heading: string; body: string; citations: string[] }export interface AgentOutput { title: string; sections: Section[]; gaps: string[]; openQuestions: string[] }export interface AgentResult extends AgentOutput { requiresReview: boolean }export interface EducationAccreditationEvidenceConfig { adapter: AdapterFactory memory?: ChatMemory observers?: Observer[] onConfirm?: (toolCall: ToolCall) => boolean | Promise<boolean> maxSteps?: number}const Output = z.object({ title: z.string(), sections: z.array(z.object({ heading: z.string(), body: z.string(), citations: z.array(z.string()).default([]) })).min(1), gaps: z.array(z.string()).default([]), openQuestions: z.array(z.string()).default([]),})const toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7const skill = { name: 'education-accreditation-evidence', description: "Accreditation Evidence — typed output agent (draft spec).", systemPrompt: `You are Accreditation Evidence. Accreditation prep. Output: Evidence typed.Draft sections with citations from input. Gaps for missing facts.NEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.${UNTRUSTED_CONTENT_DIRECTIVE}Call submit_accreditation_evidence exactly once. Stop.`, tools: ['submit_accreditation_evidence'],}export function createEducationAccreditationEvidenceAgent(config: EducationAccreditationEvidenceConfig) { const submit = (): ToolDefinition => defineZodTool({ name: 'submit_accreditation_evidence', description: 'Submit result. Once.', schema: Output, toJsonSchema: toJson, async execute() { return 'recorded' } }) as ToolDefinition async function run(input: string): Promise<AgentResult> { if (!input?.trim()) throw new Error('education-accreditation-evidence requires non-empty input') const result = await invokeStructured({ adapter: config.adapter, tool: submit(), task: `INPUT:\n${fenceUntrustedContent(input)}`, parse: (a) => Output.parse(a), skill, memory: config.memory, observers: config.observers, onConfirm: config.onConfirm, maxSteps: config.maxSteps ?? 4, }) return { ...result, requiresReview: true } } return { name: 'education-accreditation-evidence', run, asHandle() { return { name: 'education-accreditation-evidence', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } }, }}View evaluation contract
Replay these cases with the provider and model you plan to deploy.
import type { EvalSuite } from '@agentskit/eval'export const suite: EvalSuite = { name: 'education-accreditation-evidence', cases: [ { input: 'Complete input for Accreditation Evidence: Accreditation prep. Provide full structured output.', expected: (r: string) => r.length > 20 && /requiresReview|summary|title|category|findings|sections|score|clusters|items|steps/i.test(r) }, { input: 'Minimal input.', expected: (r: string) => /gap|openQuestion/i.test(r) || r.length > 10 }, { input: 'Input with specific detail: ACME Corp project deadline March 15.', expected: (r: string) => /ACME|March|15/i.test(r) || /gap/i.test(r) }, { input: 'Empty context — only says "process this".', expected: (r: string) => r.length > 5 }, ],}Was this agent useful?
Your response helps us prioritize agent quality.