Vibe Coder 实战指南

7.1 MCP 消费最佳实践

Do’s(最佳实践)

实践 描述 原因
审核公共 Server 连接前审查开源 MCP Server 代码 防止恶意代码访问文件系统/凭证
使用 RAG for tools 动态加载工具,任务完成后移除上下文 防止注意力稀释
依赖内部 API Gateway 优先使用内部 Registry 确保数据 schema 审核和治理
使用 MCP Inspector Agent 幻觉时查原始传输数据,而非盲改提示 快速定位问题
包含 HITL 调用工具前向用户展示输入 防止恶意/意外数据泄露
审计日志 记录工具使用日志 合规和追溯

Don’ts(常见陷阱)

陷阱 描述 替代方案
可消费却自建 能找到现有 MCP Server 却手写 REST wrapper 先搜索 Registry,遵循”universal outlet”哲学
生产用公共 MCP 将核心业务逻辑绑定未审核公共 endpoint 仅用于原型,生产用官方托管服务
硬编码凭证 将 API keys 直接写入提示或脚本 使用环境变量传递给 MCP Server
直连生产环境 MCP Server 连接生产数据和系统 使用开发项目,确保非生产/混淆数据
写模式用于更新 必须连接真实数据时 设置 Server 为 read-only 模式
宽 Project 访问 MCP Server 可访问所有 Projects 限制到特定 Project,最小权限原则

7.2 A2UI 生成最佳实践

使用 a2ui-agent-sdk

# pip install a2ui-agent-sdk google-adk
import asyncio, json
import jsonschema
from a2ui.schema.manager import A2uiSchemaManager
from a2ui.basic_catalog.provider import BasicCatalog
from a2ui.schema.constants import VERSION_0_9
from a2ui.parser.parser import parse_response
from google.adk.agents import LlmAgent
from google.adk.models import Gemini
from google.adk.runners import InMemoryRunner
from google.genai import types

# 1. SDK 加载 catalog,构建 validator,渲染系统提示(含 schema 和示例)
schema_manager = A2uiSchemaManager(
    version=VERSION_0_9,
    catalogs=[BasicCatalog.get_config(version=VERSION_0_9)]
)
catalog = schema_manager.get_selected_catalog()

agent = LlmAgent(
    model=Gemini(model="gemini-flash-latest"),
    name="ui_agent",
    instruction=schema_manager.generate_system_prompt(
        role_description="You generate interactive UIs as A2UI v0.9 messages.",
        ui_description="Use Cards, Lists, ChoicePickers, and Buttons to present data.",
        include_schema=True,
        include_examples=True
    )
)

# 2. 运行 Agent,解析 <a2ui-json> blocks,验证 schema
async def create_ui(intent: str, data: dict, max_retries: int = 3) -> list:
    runner = InMemoryRunner(agent=agent, app_name="ui_demo")
    session = await runner.session_service.create_session(
        app_name="ui_demo", user_id="u",
        state={"expression": "{expression}"}  # escapes SDK's templating placeholder
    )
    
    query = f"{intent}\n\nData: {json.dumps(data)}"
    last_error = None
    
    for _ in range(max_retries + 1):
        chunks = []
        msg = types.Content(role="user", parts=[types.Part(text=query)])
        async for ev in runner.run_async(user_id="u", session_id=session.id, new_message=msg):
            if ev.content and ev.content.parts:
                chunks.extend(p.text for p in ev.content.parts if p.text)
        
        blocks = [rp.a2ui_json for rp in parse_response("".join(chunks)) if rp.a2ui_json]
        
        try:
            for b in blocks:
                for m in (b if isinstance(b, list) else [b]):
                    catalog.validator.validate(m)
            return blocks
        except jsonschema.ValidationError as e:
            last_error = e
            path = "/".join(str(p) for p in e.absolute_path)
            query = (
                f"Your previous response failed schema validation at {path}: "
                f"{e.message[:200]}\nFix this and retry: {intent}\nData: {json.dumps(data)}"
            )
    
    raise ValueError(f"Schema validation failed after {max_retries} retries: {last_error}")

关键: - A2uiSchemaManager 自动生成系统提示(含 schema + 示例) - 自动 schema 验证 - 失败时重试

Hybrid Output(混合输出)

提供数据和 UI,让消费者选择:

{
  "data": {"sales": [...]},
  "ui": {"version": "v0.9", "updateComponents": {"surfaceId": "main", "components": [...]}},
  "ui_available": true
}

API 客户端:忽略 ui,只用 data
人类用户客户端:渲染 A2UI 消息