LikeC4 MCP 渲染载荷瘦身:`render-view`/`preview-view` 的视图级模型裁剪与 `fullModel` 全量模式
LikeC4 MCP 渲染载荷瘦身render-view/preview-view的视图级模型裁剪与fullModel全量模式【免费下载链接】likec4Visualize, collaborate, and evolve the software architecture with always actual and live diagrams from your code项目地址: https://gitcode.com/GitHub_Trending/li/likec4本篇技术指南围绕 LikeC4 开源仓库中likec4/mcp包的一次 Patch 变更.changeset/tidy-mcp-render-payloads.md展开render-view与preview-view两个 MCP 工具在返回渲染载荷时默认只携带所选视图真正需要的模型数据并将完整模型改由显式的fullModel: true参数按需请求。读完本文你将理解该载荷裁剪策略的动机、buildRenderPayload的源码级裁剪逻辑、fullModel参数的使用方式与验证方法并能据此在集成 LikeC4 MCP 时正确权衡响应体积与数据完整性。变更背景MCP 工具响应为何需要瘦身likec4/mcp是 LikeC4 提供的 Model Context Protocol 服务器包通过stdio传输对外暴露一组工具供 Claude 等 AI 助手查询架构模型、渲染架构视图。其中两个渲染类工具工具清单见 packages/mcp/README.md承担着把视图变成可视化结果的重任render-view把项目中已存在的视图渲染为可交互图表缩放/平移/自适应以内联方式呈现在聊天中preview-view把一段 DSL 文本定义的全新视图结合项目真实元素进行渲染预览不落盘用于在真正创建视图前迭代调优。这两个工具都通过structuredContent返回完整载荷其中包含布局后的视图nodes/edges/bounds以及配套的模型数据。在大型架构仓库中模型可能包含成百上千个元素、关系与部署节点如果每次渲染都把整个模型的序列化结果原样回传structuredContent会迅速膨胀到数百 KB 乃至数 MB既浪费 token 与网络带宽也拖慢 AI 助手的响应与后续推理。本次变更正是对这一问题的针对性优化默认只返回所选视图所需的模型数据把请求完整模型变成显式选择。变更内容原文.changeset/tidy-mcp-render-payloads.mdReducerender-viewandpreview-viewpayloads by returning only model data required by the selected view. SetfullModeltotrueto request the complete model.即默认裁剪到视图所需的最小模型数据子集需要全量数据时调用方显式传入fullModel: true。核心实现buildRenderPayload的视图级裁剪载荷构建的统一入口位于 packages/mcp/src/tools/_common.ts。RenderPayload接口定义了载荷形状export interface RenderPayload { [key: string]: unknown id: string // 视图 id title: string // 视图标题 project: string // 项目 id view: LayoutedView // 布局后的视图节点、边、坐标 model: Recordstring, unknown // 模型数据默认按视图裁剪 }buildRenderPayload依据fullModel参数决定模型数据的来源export function buildRenderPayload(params: { projectId: string viewId: string title: string layoutedView: LayoutedView model: RenderModel fullModel?: boolean }): RenderPayload { const model params.fullModel ? { ...params.model.$data, // 完整模型数据 views: { ...params.model.$data.views, [params.viewId]: params.layoutedView }, } : buildViewScopedModel(params.model, params.layoutedView) // 视图级裁剪 // ... }fullModel: true时直接展开model.$data完整模型仅把当前视图的布局结果覆盖写入views字段即全量模型 当前视图的布局默认情况下fullModel缺省或为false走buildViewScopedModel只保留渲染当前视图必需的记录。buildViewScopedModel如何算出一个视图需要哪些模型数据裁剪的核心逻辑在buildViewScopedModelpackages/mcp/src/tools/_common.ts它并非简单按 ID 白名单过滤而是从视图的节点与边出发进行图遍历式收集元素收集includeElement对于每个含modelRef的节点把该元素及其全部祖先element.ancestors()加入集合——因为渲染子元素时容器、边界框等祖先上下文也必须存在部署收集includeDeployment对含deploymentRef的部署节点收集部署元素及其祖先若该部署元素是某个逻辑元素的实例element.isInstance()同时把对应的逻辑元素也纳入关系收集遍历布局后的每条边layoutedView.edges对边上的每个relationsid 查回模型关系。模型关系isModelRelation()记录其 source/target 元素部署关系则同时解析其 source/target 的部署引用与实例元素视图锚点若视图是元素视图_type element且声明了viewOf也纳入该锚点元素。收集完成后用pickRecord对模型各记录表做键级过滤function pickRecordT(record: ReadonlyRecordstring, T, ids: ReadonlySetstring): Recordstring, T { return Object.fromEntries(Object.entries(record).filter(([id]) ids.has(id))) }最终输出结构为return { ...data, elements: pickRecord(data.elements, elementIds), imports, // 跨项目导入元素同样按需过滤 relations: pickRecord(data.relations, relationIds), deployments: { elements: pickRecord(data.deployments.elements, deploymentIds), relations: pickRecord(data.deployments.relations, deploymentRelationIds), }, views: { [layoutedView.id]: layoutedView }, // 只保留当前视图 manualLayouts: {}, // 裁剪掉手动布局数据 }可以看到除了elements/relations/deployments跨项目imports也会按是否被当前视图引用过滤且views只保留当前视图、manualLayouts直接置空。specification、globals、project等渲染所需的全局元数据仍被完整保留——因为LikeC4Diagram会无条件读取model.specificationtag 颜色等来驱动样式解析这从另一个角度解释了为什么不能只回传视图本身。载荷中的 SVG 图标内联buildRenderPayload还顺带处理了本地 SVG 图标引用inlineLocalSvgIconspackages/mcp/src/tools/_common.ts会递归扫描视图与模型数据把以file:协议开头且指向.svg的icon字段读取为data:image/svgxml,...内联值这样嵌入的图表 UI 无需访问宿主文件系统即可显示图标读取失败文件不存在等则替换为null避免载荷携带失效路径。该行为在单元测试 packages/mcp/src/tools/_common.spec.ts 中有专门验证并保证不修改原始视图与模型对象view.nodes[0]?.icon在调用后仍是原始file:URI。两个工具如何暴露fullModelrender-view渲染已存在的视图工具定义位于 packages/mcp/src/tools/render-view.ts其输入 schema 中fullModel的声明与描述为inputSchema: mcpToolSchema({ viewId: z.string().describe(View id (name)), project: projectIdSchema, fullModel: z.boolean().default(false) .describe(Include the complete model instead of data scoped to this view), render: renderOptionsSchema, })请求参数汇总参数类型默认值说明viewIdstring—视图 id名称projectstringdefault项目 id省略时用defaultfullModelbooleanfalse是否返回完整模型默认只返回视图作用域数据render.sizecompact \| standard \| largestandard初始画布尺寸提示render.fitViewbooleantrue是否初始自适应缩放适配画布render.initialZoomnumber无初始缩放级别会覆盖fitView取值范围受likec4/diagram的MinZoom/MaxZoom约束见 render-view.ts执行流程解析项目 id → 获取layoutedModel→ 按viewId查找视图不存在或未布局则返回isError文本错误→ 取出viewModel.$layouted布局结果 → 调buildRenderPayload构造structuredContent并把render选项一并回传供配套 UI 消费。render-view配套的嵌入式 UI 位于 packages/mcp/src/app-ui/render-view.client.tsx它把structuredContent中的model交给LikeC4Model.create(result.model)重建出真实LikeC4Model再通过LikeC4ModelProviderLikeC4Diagram渲染支持 pannable/zoomable/fitView/元素与关系详情等并对外暴露data-testidmcp-render-view-ready就绪标记——这正好解释了默认裁剪模型的必要性UI 需要的只是能构建出当前视图可用的 LikeC4Model的那部分数据。preview-view渲染 DSL 草稿视图工具定义位于 packages/mcp/src/tools/preview-view.ts输入与render-view不同核心参数是dslinputSchema: mcpToolSchema({ dsl: z.string().describe(A single view id ... { ... } LikeC4 DSL definition), project: projectIdSchema, fullModel: z.boolean().default(false) .describe(Include the complete model instead of data scoped to this view), })preview-view的关键行为不落盘把项目现有文档收集为虚拟源码sources再把dsl包进views { ... }块追加为一个随机命名的虚拟文件通过fromSources构建独立的临时生产实例进行解析、计算与布局与真实项目完全隔离preview-view.ts视图 id 必须是新的若dsl中声明的视图 id 与项目已有视图冲突直接返回错误提示改用其他 id 或走render-viewpreview-view.ts仅识别view id ...形式id 提取依赖正则/^\s*view\s([A-Za-z_][\w-]*)/dynamic view或deployment view会落入通用找不到view id错误分支预览样式可能不完全一致自定义主题/样式扩展不会应用到预览中最终同样通过buildRenderPayload构造载荷fullModel: args.fullModel并返回Rendered preview of view title的文本回退。测试验证裁剪生效且载荷体积受限本次变更的正确性在单元测试与集成测试中均有覆盖。单元测试packages/mcp/src/tools/_common.spec.ts 构造了一个含无关元素/导入/关系/部署节点的模型断言默认裁剪后elements仅含[root, root.child]imports仅保留被引用的外部项目元素relations、deployments.elements、deployments.relations均只含选中视图涉及的记录views只剩当前视图manualLayouts为{}fullModel: true时所有unused记录、全部 views 与manualLayouts原样保留。集成测试packages/mcp/src/tests/render-view.int.spec.ts 使用包含 250 个无关元素每个元素还带 500 字符描述的 DSL 实测默认调用render-view后model.elements的键恰好是[selected, peer, selected.child]序列化结果中不包含未入视图的Hidden元素且整个载荷Buffer.byteLength(JSON.stringify(content)) 100_000——即在大模型场景下把响应压缩到 100 KB 以内fullModel: true时unrelated元素与unrelatedView视图均出现在载荷中。preview-view集成测试packages/mcp/src/tests/preview-view.int.spec.ts同样验证了默认视图级裁剪 /fullModel全量返回两条路径。使用建议与取舍默认fullModel省略或false适合绝大多数场景AI 助手通常只需要看到/渲染某一个视图视图作用域模型足以驱动LikeC4ModelProviderLikeC4Diagram完成渲染且天然避免了无关元素、关系与跨项目导入数据占据上下文fullModel: true适用于需要基于全量模型进行推理的场景例如在预览新视图时同时考察其与全局元素/关系的关联、跨视图一致性分析等代价是载荷随模型规模线性增长在极端测试数据下可达数百 KB 以上两个工具都是只读、幂等的readOnlyHint/idempotentHint可以放心重复调用需要权衡响应大小时优先依赖默认裁剪仅在明确需要全局视角时开启fullModel。如需查看完整实现与测试可继续深入本仓库载荷构建逻辑在 packages/mcp/src/tools/_common.ts工具入口分别在 packages/mcp/src/tools/render-view.ts 与 packages/mcp/src/tools/preview-view.ts配套 UI 在 packages/mcp/src/app-ui/render-view.client.tsx相关变更历史记录于 packages/mcp/CHANGELOG.md。【免费下载链接】likec4Visualize, collaborate, and evolve the software architecture with always actual and live diagrams from your code项目地址: https://gitcode.com/GitHub_Trending/li/likec4创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →