Support structured outputs (JSON schema) per message, passed through to provider
- Ngôn ngữ chính
- Java
- Star
- 10.5k
- Fork
- 1.5k
- Merge trung bình
- 1 ngày 11 giờ
- Pull request đã merge (30 ngày)
- 128
Mô tả
## Summary
The Copilot SDK should expose first-class support for **structured outputs** (JSON schema–constrained responses) when targeting model providers that natively support the feature — OpenAI (`response_format: { type: "json_schema", ... }`) and Anthropic (structured output / tool-schema). The schema must be settable **per message** and passed through unchanged to the provider.
## Motivation
The primary use case is **deterministic agent flows that operate on the output of Copilot Studio agents**.
In Copilot Studio, an agent turn is frequently a step inside a larger orchestrated agent flow — its output is not just rendered to a user, it's fed into:
- Agent flows that expect specific fields in the output
- Routing/branching logic that switches on a category, intent, or decision
These consumers require **stable, schema-validated JSON** from the agent turn. Today the SDK only emits free-form assistant text, which forces every agent flow to either:
1. Post-parse model prose with regex / JSON-extraction heuristics — brittle and silently breaks when the model rephrases.
2. Coerce JSON via a fake single-tool tool-call — adds a round-trip per turn, pollutes tool-use telemetry, and confuses `preToolUse` hooks and authoring UX.
3. Rewrite the outgoing HTTP body in an LLM interceptor to inject `response_format` — fights the SDK's own retry/streaming logic and is unsupported.
Both OpenAI and Anthropic already accept a JSON schema directly on the request. The SDK is the only layer blocking Copilot Studio from getting deterministic agent output end-to-end.
## Proposed API
Structured output must be **per message**, because different turns in an agent flow need different schemas (classify → plan → extract → summarize).
```ts
await session.sendMessage({
content: "Classify this support ticket.",
responseFormat: {
type: "json_schema",
schema: {
name: "TicketClassification",
strict: true,
schema: {
type: "object",
properties: {
category: { type: "string", enum: ["billing", "technical", "other"] },
priority: { type: "string", enum: ["low", "medium", "high"] },
summary: { type: "string" }
},
required: ["category", "priority", "summary"],
additionalProperties: false
}
}
}
});
```
### Requirements
1. **Per-message setting** — `responseFormat` accepted on `sendMessage` / equivalent. Optional; absent ⇒ current behavior.
2. **Schema passthrough** — Forwarded verbatim to the provider request:
- OpenAI BYOM: `response_format: { type: "json_schema", json_schema: }`
- Anthropic BYOM: equivalent structured output / tool-schema mechanism
3. **Typed result on the assistant message** — Parsed JSON exposed on the resulting message (e.g., `message.structuredOutput`) so agent flows can bind to fields without re-parsing.
4. **Streaming compatible** — Final structured payload available on turn completion.
5. **Hook/interceptor friendly** — `preToolUse` hooks and raw-HTTP interceptors observe the schema in the outgoing body unchanged.
6. **Provider capability check** — Clear error if the target provider does not support structured output (rather than silently dropping the field).
## Non-goals
- Inventing a new schema dialect — accept JSON Schema as the providers do.
- Cross-provider schema translation beyond what each provider natively accepts.
## Acceptance criteria
- [ ] `responseFormat` (JSON schema) accepted on per-message send APIs
- [ ] Forwarded verbatim to OpenAI and Anthropic provider requests
- [ ] Sructured payload exposed on the resulting assistant message
- [ ] Works with streaming and with existing hook/interceptor surfaces
- [ ] Clear error when targeting a provider that doesn't support it
## References
- OpenAI Structured Outputs: https://platform.openai.com/docs/guides/structured-outputs
- Anthropic structured output / tool schemas: https://docs.anthropic.com/en/docs/build-with-claude/tool-use
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.