Support structured outputs (JSON schema) per message, passed through to provider
- 主要语言
- Java
- 星标
- 10.5k
- 派生
- 1.5k
- 平均合并
- 1 天 14 小时
- 30 天内合并 PR
- 129
描述
## 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
贡献指南
调研方向
从 sendMessage 或等效 API 开始,跟踪每条消息的选项如何传递到 OpenAI 和 Anthropic provider 的请求中。然后继续跟踪 assistant-message 完成和流式处理路径,以及 preToolUse hook 和 raw-HTTP 拦截器。完成的标准是 responseFormat 得以保留、structuredOutput 暴露在 assistant message 上、不支持的 provider 报告清晰的错误,并且涵盖列出的验收标准。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- java, typescript
- 领域
- api, backend-api-design
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 活跃
- 描述清晰度
- 基本清楚
- 新手友好度
- 38/100