Brainstorming Summary · 2026-07-08
SDK 能力增强:运行配置、评测集成与会话级资产
本文整理本轮设计讨论的关键判断,尤其记录用户的回答、关注点和最终收敛方向。目标不是实现细节清单,而是保留架构决策的来龙去脉,便于后续写正式 spec 和实施计划。
背景与动机
用户希望增强 SDK,使其适应更多外部环境:别人安装包后直接集成、用于 benchmark、用于自动评测、用于专业调试。部分 BA 页面不适合暴露的高级能力,可以通过 SDK 提供,例如控制上下文压缩比例。
参考材料是 ~/artifacts/pr-1192-eval-judge-summary.html。该报告的核心启发是:评测 harness 应该外置,BA 主体不应合入大量 eval 专用 route、CLI、OpenAPI 类型和镜像构建逻辑。BA 更适合补通用 SDK 能力和少量运行时参数。
现状观察
- Python SDK 已有 async client、session、upload、download、history、headless runner、session env、session skill 上传。
- TS SDK 已有
HeadlessResource、session APIs、solution APIs、skill/resource 能力,且headless.runInSession/runWithSession已具雏形。 - 后端创建 session 已支持
solution_id + biz_role_id、primary_skill_id、env、disable_tools、memory_enabled、enable_thinking。 - host 内部已有
session_solution机制,可把加载好的 Solution 绑定到 session-local,而不进入全局 registry。 - 上下文压缩当前主要由全局
config.compaction_ratio驱动,还不是 session/run 级 SDK 参数。
讨论中的关键选择
| 议题 | 用户回答 / 关注点 | 设计结论 |
|---|---|---|
| 先做哪一层 | 选择“先设计统一 SDK 能力模型”。不先限定 Python 或 TS。 | 先抽象能力模型,再拆首批实现。 |
| 首要使用场景 | 选择 benchmark / 评测 harness 和高级开发者工具。 | API 需要支持可重复运行、trace、文件归档、运行参数控制和调试 payload。 |
| 参数层级 | session 默认值和 run 覆盖都要有。 | 引入 SessionProfile + RunOptions,记录每次实际生效配置。 |
| 首批参数 | 选择稳定能力 + 专业控制,但后来明确不需要 max_turns。 |
纳入 model、compaction_ratio、thinking、memory、env、runtime_env、disable_tools、headless、schema、trace;不纳入 max_turns。 |
| Python / TS 范围 | 两个 SDK 用的人都很多,需要同步开发。 | 首批要求 Python SDK 和 TS SDK 概念、命名、能力同步。 |
| 外部工具桥 | 一开始未确定,后来明确“一个 MCP stdio 脚本放在 skill 里,SKILL.md 提一句,智能体会用”。 | 不做 server-side external tool bridge,不恢复 host MCP provider;MCP stdio 作为 SkillBundle 资产。 |
| 上传 solution | 需要允许用户上传 solution;也可能选择 hub 已有 solution。 | 支持 ExistingSolutionRef 和 PreparedSolutionAsset 两种来源。 |
| 绑定 solution 的时机 | 指出创建 session 时就必须知道是否绑定 solution。 | 采用 prepare + create:先上传临时 asset,创建 session 时带 asset id 绑定。 |
| solution 上传位置 | 询问“solution 打算上传到哪里”。 | 上传到 server 管理的临时 session asset store,不进全局 registry,不先进 session workspace。 |
最终收敛方案
统一 SDK 能力模型由三块组成:运行配置、会话级资产、运行证据收集。评测逻辑、业务环境和 MCP server 都保持外置;BA server 只补通用能力。
Solution 资产设计
支持两类来源:
ExistingSolutionRef:选择已加载或从 hub/registry ensure 下来的 solution,创建 session 时传solution_id和biz_role_id。PreparedSolutionAsset:用户上传 zip / bundle,server 校验后返回asset_id,创建 session 时传session_solution_asset_id和biz_role_id。
Asset Store
<data_dir>/session-assets/solutions/<user_id>/<asset_id>/
source.zip
unpacked/
solution.yaml
roles/
skills/
metadata.json
Skill 与 MCP Stdio
MCP stdio 不做任何 server 级 tool bridge。外部 harness 把 MCP server 脚本作为 SkillBundle 资产上传,SKILL.md 告诉智能体如何使用。
invoice_mcp_skill/
SKILL.md
mcp_server.py
config.json
helpers/
这符合当前仓库里“host MCP 注入链路废弃,转向沙盒内 mcp2cli / skill 使用”的方向。智能体通过 skill 说明和已有工具运行 MCP stdio,不需要 BA server 理解 MCP 协议。
SDK API 草案
Python
solution = await client.solutions.prepare("./solutions/invoice_eval")
session = await client.sessions.create_with_profile(
intent="invoice benchmark",
profile=SessionProfile(
solution=PreparedSolutionAsset(
asset_id=solution.asset_id,
biz_role_id="default",
),
skills=[SkillBundle.from_dir("./skills/invoice_mcp")],
model="...",
compaction_ratio=0.5,
enable_thinking=True,
memory_enabled=False,
disable_tools=["AskUserQuestion", "Agent"],
env={"ATTEMPT_ID": "attempt-001"},
),
)
run = await client.runs.run(
session.id,
"执行 case-001,并提交结构化结果",
options=RunOptions(
headless=True,
output_schema=CaseResultSchema,
runtime_env={"CASE_ID": "case-001"},
timeout_secs=600,
trace=True,
),
)
trace = await client.runs.collect_trace(run)
TypeScript
const prepared = await client.solutions.prepareFromDirectory("./solutions/invoice_eval")
const session = await client.sessions.createWithProfile({
intent: "invoice benchmark",
profile: {
solution: {
kind: "prepared",
assetId: prepared.assetId,
bizRoleId: "default",
},
skills: [SkillBundle.fromDirectory("./skills/invoice_mcp")],
model: "...",
compactionRatio: 0.5,
enableThinking: true,
memoryEnabled: false,
disableTools: ["AskUserQuestion", "Agent"],
env: { ATTEMPT_ID: "attempt-001" },
},
})
const run = await client.runs.run(session.id, "执行 case-001,并提交结构化结果", {
headless: true,
outputSchema: caseResultSchema,
runtimeEnv: { CASE_ID: "case-001" },
timeoutMs: 600_000,
trace: true,
})
后端契约草案
| 接口 / 字段 | 用途 | 说明 |
|---|---|---|
POST /api/session-assets/solutions |
上传临时 solution asset | 返回 asset_id、solution_id、roles、expires_at。 |
POST /api/solutions/ensure-from-registry |
确保 hub/registry solution 可用 | 现有接口,SDK 统一封装。 |
POST /api/sessions |
创建 session | 扩展支持 session_solution_asset_id、biz_role_id、compaction_ratio。 |
chat:send |
单次 run | 扩展支持 run 级 compaction_ratio,继续使用已有 headless、output_schema、runtime_env。 |
| run metadata | 复现与审计 | 记录最终生效的 session/run 配置。 |
明确不做
- 不把 PR #1192 的 eval 专用 server route 合入 BA 主体。
- 不做 server-side external tool bridge。
- 不恢复已废弃的 host MCP 动态注入链路。
- 首批不加入
max_turns。 - 上传的 session-scoped solution 不进入
/api/solutions,不污染全局或个人 registry。
待正式 Spec 展开的点
- session asset store 的 TTL、清理策略、大小限制、路径穿越校验、zip 解压安全。
- session-scoped solution asset 如何加载为
Solution,并传入已有engine.create_session(..., session_solution=...)。 compaction_ratio如何从全局配置扩展到 session 默认和 run 覆盖。- Python / TS SDK 的类型命名、错误语义和返回 envelope 对齐。
- trace collector 的最小稳定字段:events、history、payload logs、files、final result。
- SkillBundle 目录打包和 session skill 上传如何在两端 SDK 保持一致。