Answering
KIT · constant · 运行时值
导入
import { Answering } from '@jangts/agent-core/kits/answering';import { Answering } from '@jangts/agent-core/kits/answering';其他公开入口:@jangts/agent-core/types、@jangts/agent-core/kits/answering、@jangts/agent-core/kits。
定义
成员目录
| 成员 | 用途 |
|---|---|
defineAnswerTaskCatalog | 完整输入输出见下方重载。 |
defineAnswerReaderCatalog | 完整输入输出见下方重载。 |
defineAnswerCheckCatalog | 完整输入输出见下方重载。 |
defineAnswerFlow | 完整输入输出见下方重载。 |
validateAnswerBatch | 完整输入输出见下方重载。 |
成员详情
defineAnswerTaskCatalog
Answering.defineAnswerTaskCatalog<Input, Evidence, App, Data = unknown>(definitions: readonly AnswerTaskDefinition<Input, Data>[], ports: AnswerTaskPorts<Input, Evidence, App, Data>): Readonly<{ describe: () => { inputJsonSchema: Readonly<Record<string, unknown>>; id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; metadata: Data; }[]; read(request: { taskId: string; input: unknown; }, context: OperationContext<App>): Evidence; readAsync(request: { taskId: string; input: unknown; }, context: OperationContext<App>): Promise<Evidence>; definitions: readonly Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>[]; ids(): readonly string[]; values(): IterableIterator<Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>>; entries(): IterableIterator<readonly [string, Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>]>; has(id: string): boolean; get(id: string): Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }> | undefined; require(id: string): Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>; }>Compile the answer task catalog from its declarations and shared ports.
Task ids, schemas, readers, outputs and checks have one compiled authority: a task can only reference a reader or check that the ports actually registered, and metadata is cloned and frozen so later mutation by the caller cannot change a registered task.
| 类型参数 | 约束 | 默认类型 |
|---|---|---|
Input | — | — |
Evidence | — | — |
App | — | — |
Data | — | unknown |
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
definitions | readonly AnswerTaskDefinition<Input, Data>[] | 必需 | — |
ports | AnswerTaskPorts<Input, Evidence, App, Data> | 必需 | — |
ports 的字段
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
readers | ReadonlyCatalog<AnswerReader<Input, Evidence, App, Data>> | 必需 | 只读。见类型定义及调用场景。 |
outputs | ReadonlyCatalog<{ readonly id: string; }> | 必需 | 只读。见类型定义及调用场景。 |
checks | ReadonlyCatalog<{ readonly id: string; }> | 必需 | 只读。见类型定义及调用场景。 |
assertDefinition | ((task: Readonly<AnswerTaskDefinition<Input, Data>>) => void) | undefined | 可省略 | Extra App assertion over a raw definition, before it is compiled. |
返回: Readonly<{ describe: () => { inputJsonSchema: Readonly<Record<string, unknown>>; id: string; description: string; readerId: string; outputId: string; scopeId: string \| undefined; goalIds: readonly any[]; checkIds: readonly any[]; metadata: Data; }[]; read(request: { taskId: string; input: unknown; }, context: OperationContext<App>): Evidence; readAsync(request: { taskId: string; input: unknown; }, context: OperationContext<App>): Promise<Evidence>; definitions: readonly Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string \| undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>[]; ids(): readonly string[]; values(): IterableIterator<Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string \| undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>>; entries(): IterableIterator<readonly [string, Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string \| undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>]>; has(id: string): boolean; get(id: string): Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string \| undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }> \| undefined; require(id: string): Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string \| undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>; }>。
返回值结构
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
describe | () => { inputJsonSchema: Readonly<Record<string, unknown>>; id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; metadata: Data; }[] | 必需 | Task metadata with the JSON schema flattened for model or admin presentation. |
read | (request: { taskId: string; input: unknown; }, context: OperationContext<App>) => Evidence | 必需 | Read evidence through a task's registered reader, synchronously. |
readAsync | (request: { taskId: string; input: unknown; }, context: OperationContext<App>) => Promise<Evidence> | 必需 | Read evidence through a task's registered reader, awaiting an async reader. |
definitions | readonly Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>[] | 必需 | 只读。Definitions in registration order; each entry is frozen by the implementation. |
ids | () => readonly string[] | 必需 | Ids in the same order as definitions. |
values | () => IterableIterator<Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>> | 必需 | 见类型定义及调用场景。 |
entries | () => IterableIterator<readonly [string, Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }>]> | 必需 | 见类型定义及调用场景。 |
has | (id: string) => boolean | 必需 | 见类型定义及调用场景。 |
get | (id: string) => Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }> | undefined | 必需 | Returns the definition or undefined; the caller decides whether absence is an error. |
require | (id: string) => Readonly<{ id: string; description: string; readerId: string; outputId: string; scopeId: string | undefined; goalIds: readonly any[]; checkIds: readonly any[]; inputSchema: SchemaAdapter<Input>; metadata: Data; }> | 必需 | Returns the definition or throws; use when the id is a required reference. |
defineAnswerReaderCatalog
Answering.defineAnswerReaderCatalog<Input, Evidence, App, Data = unknown>(definitions: readonly AnswerReader<Input, Evidence, App, Data>[]): ReadonlyCatalog<{ id: string; read: (input: Input, context: OperationContext<App> & { readonly task: Readonly<AnswerTaskDefinition<Input, Data>>; }) => MaybePromise<Evidence>; }>Compile a reader catalog.
| 类型参数 | 约束 | 默认类型 |
|---|---|---|
Input | — | — |
Evidence | — | — |
App | — | — |
Data | — | unknown |
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
definitions | readonly AnswerReader<Input, Evidence, App, Data>[] | 必需 | — |
返回: ReadonlyCatalog<{ id: string; read: (input: Input, context: OperationContext<App> & { readonly task: Readonly<AnswerTaskDefinition<Input, Data>>; }) => MaybePromise<Evidence>; }>。
返回值结构
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
definitions | readonly Readonly<{ id: string; read: (input: Input, context: OperationContext<App> & { readonly task: Readonly<AnswerTaskDefinition<Input, Data>>; }) => MaybePromise<Evidence>; }>[] | 必需 | 只读。Definitions in registration order; each entry is frozen by the implementation. |
ids | () => readonly string[] | 必需 | Ids in the same order as definitions. |
values | () => IterableIterator<Readonly<{ id: string; read: (input: Input, context: OperationContext<App> & { readonly task: Readonly<AnswerTaskDefinition<Input, Data>>; }) => MaybePromise<Evidence>; }>> | 必需 | 见类型定义及调用场景。 |
entries | () => IterableIterator<readonly [string, Readonly<{ id: string; read: (input: Input, context: OperationContext<App> & { readonly task: Readonly<AnswerTaskDefinition<Input, Data>>; }) => MaybePromise<Evidence>; }>]> | 必需 | 见类型定义及调用场景。 |
has | (id: string) => boolean | 必需 | 见类型定义及调用场景。 |
get | (id: string) => Readonly<{ id: string; read: (input: Input, context: OperationContext<App> & { readonly task: Readonly<AnswerTaskDefinition<Input, Data>>; }) => MaybePromise<Evidence>; }> | undefined | 必需 | Returns the definition or undefined; the caller decides whether absence is an error. |
require | (id: string) => Readonly<{ id: string; read: (input: Input, context: OperationContext<App> & { readonly task: Readonly<AnswerTaskDefinition<Input, Data>>; }) => MaybePromise<Evidence>; }> | 必需 | Returns the definition or throws; use when the id is a required reference. |
defineAnswerCheckCatalog
Answering.defineAnswerCheckCatalog<Value, App>(definitions: readonly AnswerChecker<Value, App>[]): Readonly<{ check(request: { checkIds: readonly string[]; value: Value; }, context: OperationContext<App>): AnswerCheck<Value>; definitions: readonly Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>[]; ids(): readonly string[]; values(): IterableIterator<Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>>; entries(): IterableIterator<readonly [string, Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>]>; has(id: string): boolean; get(id: string): Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }> | undefined; require(id: string): Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>; }>Compile a checker catalog.
A checker may return a replacement value; it is threaded into the next checker, so the selected ids behave like an ordered chain rather than independent assertions.
| 类型参数 | 约束 | 默认类型 |
|---|---|---|
Value | — | — |
App | — | — |
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
definitions | readonly AnswerChecker<Value, App>[] | 必需 | — |
返回: Readonly<{ check(request: { checkIds: readonly string[]; value: Value; }, context: OperationContext<App>): AnswerCheck<Value>; definitions: readonly Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>[]; ids(): readonly string[]; values(): IterableIterator<Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>>; entries(): IterableIterator<readonly [string, Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>]>; has(id: string): boolean; get(id: string): Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }> \| undefined; require(id: string): Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>; }>。
返回值结构
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
check | (request: { checkIds: readonly string[]; value: Value; }, context: OperationContext<App>) => AnswerCheck<Value> | 必需 | 见类型定义及调用场景。 |
definitions | readonly Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>[] | 必需 | 只读。Definitions in registration order; each entry is frozen by the implementation. |
ids | () => readonly string[] | 必需 | Ids in the same order as definitions. |
values | () => IterableIterator<Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>> | 必需 | 见类型定义及调用场景。 |
entries | () => IterableIterator<readonly [string, Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }>]> | 必需 | 见类型定义及调用场景。 |
has | (id: string) => boolean | 必需 | 见类型定义及调用场景。 |
get | (id: string) => Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }> | undefined | 必需 | Returns the definition or undefined; the caller decides whether absence is an error. |
require | (id: string) => Readonly<{ id: string; check: (value: Value, context: OperationContext<App>) => CheckResult<Value>; }> | 必需 | Returns the definition or throws; use when the id is a required reference. |
defineAnswerFlow
Answering.defineAnswerFlow<Data, Value, App = undefined>(definition: AnswerFlowDefinition<Data, Value, App>): Readonly<{ run(request: { inputIds: readonly string[]; items: readonly AnswerItem<Data>[]; }, context: OperationContext<App>): Promise<AnswerResult<Data, Value>[]>; }>Compile a reusable answer workflow.
Reusable answer workflow. Requests own cells and repair budgets; models remain caller-owned. The flow runs at most maxRepairs + 1 rounds: one generation pass, then one repair round per failing item set, and finally an explicit accepted/fallback/blocked result per item.
| 类型参数 | 约束 | 默认类型 |
|---|---|---|
Data | — | — |
Value | — | — |
App | — | undefined |
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
definition | AnswerFlowDefinition<Data, Value, App> | 必需 | — |
definition 的字段
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
maxItems | number | 必需 | 只读。Maximum items in one batch; must be a positive integer. |
maxRepairs | number | 必需 | 只读。Repair rounds; the flow runs at most maxRepairs + 1 rounds in total. |
reviewPolicy | "required" | "off" | "optional" | undefined | 可省略 | 只读。Review policy; defaults to optional, required blocks on an unresolved review. |
canInvoke | (context: OperationContext<App>) => boolean | 必需 | Request-level budget guard; must return boolean synchronously. |
generate | (input: { readonly items: readonly AnswerItem<Data>[]; readonly repairs?: ReadonlyMap<string, readonly AnswerIssue[]>; readonly previous?: ReadonlyMap<string, Value> | undefined; }, context: OperationContext<App>) => Promise<ReadonlyMap<string, Value>> | 必需 | Produces values for the items that still need one. repairs carries the issues of a failed attempt and previous its rejected values. |
check | (input: { readonly item: AnswerItem<Data>; readonly value: Value; }, context: OperationContext<App>) => AnswerCheck<Value> | 必需 | Local check for one generated value; must return synchronously. |
review | ((input: { readonly items: readonly { item: AnswerItem<Data>; value: Value; }[]; }, context: OperationContext<App>) => Promise<ReadonlyMap<string, AnswerCheck<Value>>>) | undefined | 可省略 | Batch review; returns one check per reviewed item and must cover the submitted items. |
fallback | (input: { readonly item: AnswerItem<Data>; readonly issues: readonly AnswerIssue[]; }, context: OperationContext<App>) => RecoveryResult<Value> | 必需 | Last resort for a failed item; handled supplies a replacement value. |
observe | ((input: { readonly stageId: string; readonly results: readonly AnswerResult<Data, Value>[]; }, context: OperationContext<App>) => MaybePromise<void>) | undefined | 可省略 | Observes a stage outcome; failures must not affect the flow result. |
返回: Readonly<{ run(request: { inputIds: readonly string[]; items: readonly AnswerItem<Data>[]; }, context: OperationContext<App>): Promise<AnswerResult<Data, Value>[]>; }>。
返回值结构
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
run | (request: { inputIds: readonly string[]; items: readonly AnswerItem<Data>[]; }, context: OperationContext<App>) => Promise<AnswerResult<Data, Value>[]> | 必需 | Run one answer batch. |
validateAnswerBatch
Answering.validateAnswerBatch<Data>(inputIds: readonly string[], items: readonly AnswerItem<Data>[], maxItems: number): voidValidate that one batch is well formed and fully covered.
| 类型参数 | 约束 | 默认类型 |
|---|---|---|
Data | — | — |
| 参数 | 类型 | 传递 | 说明 |
|---|---|---|---|
inputIds | readonly string[] | 必需 | — |
items | readonly AnswerItem<Data>[] | 必需 | — |
maxItems | number | 必需 | — |
返回: void。
使用示例
- Answering Flow:逐项生成、复核与局部修正:对已拆分的问题批次保留覆盖关系,修复失败项,不重新生成已经通过的项。
先处理一个有来源的说明问题
入门 · Node.js
离线示例直接使用已读正文,展示流程合同;换成模型生成时仍用同一个 generate 端口。
import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow<{ source: string }, string, {}>({
maxItems: 4, maxRepairs: 0, reviewPolicy: 'off', canInvoke: () => true,
async generate({ items }) { return new Map(items.map(item => [item.id, item.data.source])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: [] }),
fallback: () => ({ handled: false }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].value);import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow({
maxItems: 4, maxRepairs: 0, reviewPolicy: 'off', canInvoke: () => true,
async generate({ items }) { return new Map(items.map(item => [item.id, item.data.source])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: [] }),
fallback: () => ({ handled: false }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].value);保持 run 不变,增加复核和一次局部修正
配置 · Node.js
示例以空草稿触发一次真实局部修正;生产 review 应依据真实证据,不用字符串等号代替语义复核。
import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow<{ source: string }, string, {}>({
maxItems: 4, maxRepairs: 1, reviewPolicy: 'required', canInvoke: () => true,
async generate({ items, repairs }) { return new Map(items.map(item => [item.id, repairs?.has(item.id) ? item.data.source : ''])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: value.trim() ? [] : [{ code: 'EMPTY', message: '需要非空回答' }] }),
async review({ items }) { return new Map(items.map(({ item, value }) => [item.id, { status: value === item.data.source ? 'passed' as const : 'failed' as const, issues: [] }])); },
fallback: () => ({ handled: true, value: '当前资料不足,暂时无法回答。' }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].checks);import { Answering } from '@jangts/agent-core/kits/answering';
const flow = Answering.defineAnswerFlow({
maxItems: 4, maxRepairs: 1, reviewPolicy: 'required', canInvoke: () => true,
async generate({ items, repairs }) { return new Map(items.map(item => [item.id, repairs?.has(item.id) ? item.data.source : ''])); },
check: ({ value }) => ({ status: value.trim() ? 'passed' : 'failed', issues: value.trim() ? [] : [{ code: 'EMPTY', message: '需要非空回答' }] }),
async review({ items }) { return new Map(items.map(({ item, value }) => [item.id, { status: value === item.data.source ? 'passed' : 'failed', issues: [] }])); },
fallback: () => ({ handled: true, value: '当前资料不足,暂时无法回答。' }),
});
const result = await flow.run({ inputIds: ['question-1'], items: [{ id: 'explain', inputIds: ['question-1'], sourceStatus: 'ready', data: { source: '普通对象可以实现节点合同。' } }] }, { app: {}, signal: new AbortController().signal });
console.log(result[0].status, result[0].checks);先验证多问题覆盖,防止遗漏输入
扩展 · Node.js
import { Answering } from '@jangts/agent-core/kits/answering';
const items = [
{ id: 'define', inputIds: ['q1'], sourceStatus: 'ready' as const, data: { source: '定义节点' } },
{ id: 'run', inputIds: ['q2'], sourceStatus: 'unavailable' as const, data: { source: '' } },
];
Answering.validateAnswerBatch(['q1', 'q2'], items, 4);
console.log('两个问题均有明确处理项,包括资料不可用的项。');import { Answering } from '@jangts/agent-core/kits/answering';
const items = [
{ id: 'define', inputIds: ['q1'], sourceStatus: 'ready', data: { source: '定义节点' } },
{ id: 'run', inputIds: ['q2'], sourceStatus: 'unavailable', data: { source: '' } },
];
Answering.validateAnswerBatch(['q1', 'q2'], items, 4);
console.log('两个问题均有明确处理项,包括资料不可用的项。');