《实用笔记》:别再为每个想法都开发AI应用,开始构建MCP。
《实用笔记》操作指南:别再为每个想法都开发AI应用,开始构建MCP——专为采用该模式的团队设计的合约、校验机制及即用代码模块。
本指南将重新梳理从原始材料到可运行系统的完整流程,内容来自《别再为每个想法都构建 AI 应用——开始构建 MCP 服务器(第7部分)》。重点在于可操作的步骤、明确的检查点,以及可直接放入代码仓库的代码,无需猜测其用途。 在概览阶段,应在修改代码之前明确输入参数、各步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行相应步骤,而无需猜测隐藏的状态。 配置信息应与应用程序代码分开存放。环境文件、密钥存储和功能开关应集中于一个位置,这样操作人员无需查看整个系统结构即可进行审核。
开始之前!
在“开始之前”阶段,首先写下合同规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 需为每次调用记录工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试代理将陷入无止境的循环,耗费大量时间。
我们最初使用的MCP服务器与现在的已不同
在开发MCP服务器时,首先应明确写出接口规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合预期。 相比冗长的脚本,更应采用小型且可测试的单元。当某个步骤出错时,错误应指向单一的责任模块,而非复杂的流程链。 需为每次调用记录工具名称、参数哈希值、延迟时间以及执行结果。没有这些记录,调试代理将陷入无休止的循环,耗费大量时间。
MCP server
├── search_documents
├── create_ticket
└── get_customer
Salesforce MCP 60 capabilities
GitHub MCP 40 capabilities
Jira MCP 35 capabilities
Google Drive MCP 25 capabilities
Knowledge Base MCP 20 capabilities
Internal Platform MCP 70 capabilities
Reporting MCP 15 capabilities
Admin MCP 30 capabilities
FastMCP是这一理念的出色实现,但它并非该理念本身。
在处理 FastMCP 的过程中,一个良好的步骤是首先写下契约:所需的输入、成功信号以及部分失败时会发生什么。这样的清单能确保后续的代码修改保持一致性。 将这一阶段视为输入与验证后输出之间的契约。为相关组件命名,定义成功检测标准,并拒绝默许的部分完成。 需为每次调用记录工具名称、参数哈希值、延迟时间以及执行结果。没有这些记录,调试代理的循环会浪费大量时间。 在处理 FastMCP 的过程中,一个良好的步骤是首先写下契约:所需的输入、成功信号以及部分失败时会发生什么。这样的清单能确保后续的代码修改保持一致性。 应将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作员无需查看整个系统结构即可进行审计。
1. 工具转换:后端 API 不应自动变成代理 API
在将该阶段视为可度量的对象时,工具转换机制才能发挥最佳作用。在扩大范围之前,需记录一份理想的操作日志、一个失败案例以及回滚说明。同时文档化正常流程与恢复流程。重试机制、人工审核环节以及死信处理都是产品的一部分,而非后续需要补充的功能。应以结构明确的方案提供工具,并标注清晰的副作用信息,以便主机在自动批准之前了解哪些调用会改变状态。
salesforce_account_query_v2_internal(
q_string,
include_deleted_flag,
tenant_uuid,
raw_fields,
)
find_customer_account(
company_name,
include_archived=False,
)
Backend capability
↓
Raw MCP tool
↓
Transformation layer
↓
Agent-facing contract
2. 工具搜索:工具目录本身即可作为搜索上下文
将舞台视为可测量的表面时,两种工具搜索方式的效果最佳。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。 相较于庞大的脚本,应优先使用小型且可测试的单元。当某一步骤失败时,故障应指向单一责任点,而非复杂的流程链。 使用结构简洁的工具,并为它们添加明确的副作用标签。主机需要在自动批准之前知道哪些调用会改变状态。
connect to server
↓
list all tools
↓
put every schema into the model context
↓
ask model to choose
small discovery interface
↓
search relevant capabilities
↓
load only matching schemas
↓
execute
3. 命名空间:组合模式在引发扩展问题之前就会产生身份识别问题
将“3个命名空间组合”视为可度量的界面时,最有利于构建阶段化工作流程。在扩大范围之前,需记录一份最佳实践案例、一个失败案例以及回滚说明。 应将此阶段视为输入与已验证输出之间的契约。为相关成果命名,明确成功标准,杜绝默许的半完成状态。 需提供具有严格结构且带有明确副作用标签的工具。托管方必须在自动批准之前了解哪些调用会改变系统状态。 将“3个命名空间组合”视为可度量的界面时,最有利于构建阶段化工作流程。在扩大范围之前,需记录一份最佳实践案例、一个失败案例以及回滚说明。 配置应置于应用程序代码之外。环境文件、密钥存储及功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。
Source identity
→ Namespace
Agent usability
→ Transformation
4. 可见性:上下文工程不仅关乎文本
在“可见性”这一上下文工程阶段,应在修改代码之前明确输入内容、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品不可或缺的部分,而非后续需要补充的功能。 在网关处进行身份验证,在数据层进行重新授权。仅凭承载令牌并不足以界定租户边界。
Customer Research
├── salesforce_find_account
├── salesforce_list_opportunities
├── knowledge_search
├── web_research
└── generate_customer_report
workflow = customer_research
include:
salesforce.*
knowledge_base.*
reports.*
exclude:
admin.*
deployment.*
hr.*
5. MCP代理:一个MCP服务器可充当其他MCP服务器的网关
对于5 MCP Proxy单阶段流程,在修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。相比冗长的脚本,更应采用小型且可测试的单元。当某个步骤失败时,故障原因应能指向单一责任主体,而非复杂的流程链。应在网关处进行身份验证,在数据层再次授权——仅凭承载令牌并不足以界定租户边界。
AI client
↓
Salesforce MCP
6. 技能作为MCP资源:服务器可以分发知识,而不仅仅是操作指令
在将6项技能作为MCP阶段使用时,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 应将此阶段视为输入与已验证输出之间的契约。为相关成果命名,定义成功判定条件,并拒绝默许的半完成状态。 在网关处进行身份验证,在数据层面重新授权。仅凭承载令牌并不足以界定租户边界。 在将6项技能作为MCP阶段使用时,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个操作人员可审计的位置,无需查看整个系统结构。
7. 请求信息:能力组件可向用户请求所需资源
在处理7个“请求信息”阶段时,首先需明确相关约定:所需输入、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续代码修改的透明度。 同时记录正常流程与异常恢复路径。重试机制、人工干预环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 需为每次调用记录工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试代理将陷入无休止的循环,耗费大量时间。
8. 日志记录:对客户端有用,但生产环境下的可观测性需求更为深入
在编写8种对阶段处理有用的日志记录功能时,首先需明确相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 相比冗长的脚本,应优先选择小型且可测试的单元。当某个步骤失败时,故障应能指向单一的责任模块,而非复杂的流程链。 需为每次调用记录工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试代理将陷入无休止的循环,耗费大量时间。
9. 后台任务:MCP功能可具备执行生命周期
在处理9项后台任务中的某一阶段时,首先需明确相关契约:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 将这一阶段视为输入与验证后输出之间的契约。为相关产物命名,定义成功检测标准,并杜绝无声的半完成状态。 需记录每次调用的工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试代理将陷入无休止的循环,耗费大量时间。 在处理9项后台任务中的某一阶段时,首先需明确相关契约:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 应将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一处,以便操作人员无需查看整个系统结构即可进行审计。
10. 版本控制:一旦智能体依赖你的工具,该工具的架构就相当于一个API
在将智能体部署到不同阶段时,采用10版本控制策略的效果最佳,此时应将其视为可度量的对象。在扩大应用范围之前,先记录一份理想的操作日志、一个故障案例以及回滚说明。 同时记录正常流程和恢复流程。重试机制、人工审核环节以及错误处理方式都是产品本身的一部分,而非后续需要补充的功能。 应提供具有精简架构且带有明确副作用标签的工具。主机在自动批准之前需要知道哪些调用会改变状态。
11. 测试:要测试的是MCP接口,而不仅仅是Python函数
在将测试阶段视为可度量的对象时,11项测试效果最佳。在扩大测试范围之前,先记录一份成功的测试用例、一个失败案例以及回滚说明。 相比庞大的脚本,应优先选择小型且易于测试的单元。当某个步骤失败时,故障应指向单一的责任模块,而非复杂的流程链。 在讲解循环逻辑之前,先固定解释器及依赖项的锁定文件。笔记本电脑与持续集成环境之间的差异是API演示中最常见的隐性故障原因。
async def find_customer(company_name: str):
...
result = await find_customer("Acme")
assert result
async with Client(mcp) as client:
tools = await client.list_tools()
assert "salesforce_find_customer" in {
tool.name for tool in tools
}
result = await client.call_tool(
"salesforce_find_customer",
{"company_name": "Acme"},
)
将各部分组合起来后,服务器的样子就会大不相同
将“整合各部分”这一阶段视为可度量的工作面时效果最佳。在扩大范围之前,需记录一份理想状态示例、一个失败案例以及回滚说明。 应将此阶段视为输入与已验证输出之间的契约。为相关成果命名,明确成功标准,杜绝默许的半完成状态。 应使用具有严格结构且带有明确副作用标注的工具。主机需要在自动批准之前知晓哪些调用会改变系统状态。 将“整合各部分”这一阶段视为可度量的工作面时效果最佳。在扩大范围之前,需记录一份理想状态示例、一个失败案例以及回滚说明。 配置应置于应用程序代码之外。环境文件、密钥存储及功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。
最有趣的优化可能发生在模型看到任何内容之前
在进入最有趣的优化阶段时,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。需同时记录正常流程和异常恢复路径。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。当下一步操作是编写代码或调用工具时,应优先使用具有结构化格式且经过模式验证的输出,而非自由形式的文字描述。
从单个MCP服务器到MCP网络
在“来自某个MCP服务器阶段”这一环节中,应在修改代码之前明确输入参数、该步骤的负责人以及终止条件。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏的状态。相比庞大的脚本,更应采用小型且可测试的单元。当某个步骤失败时,故障原因应能明确指向某个具体的责任模块,而非整个复杂的流程。应在网关处进行身份验证,在数据层面重新授权——仅凭承载令牌并不足以界定租户边界。
AI client
↓
MCP server
↓
API
但在出现平台问题之前,切勿急于构建平台
在修改代码之前,需为该阶段定义输入参数、步骤负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。应将此阶段视为输入与已验证输出之间的契约:为相关成果命名、设定成功判定标准,并拒绝默许的半完成状态。在网关处进行身份验证,在数据层再次授权——仅凭承载令牌并不足以界定租户边界。在修改代码之前,需为该阶段定义输入参数、步骤负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。应将配置置于应用程序代码之外,环境文件、密钥存储及功能标志应集中存放于操作人员可审计的位置,无需查看整个系统结构。
框架是可以更换的,而架构才是核心价值所在。
在处理“框架可替换”这一阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合要求。 同时记录正常流程与异常恢复流程。重试机制、人工审核环节以及死信处理都属于产品功能的一部分,而非后续需要补充的内容。 对于每次调用,都要记录工具名称、参数哈希值、延迟时间以及最终结果。如果没有这些记录,调试过程将会浪费大量时间。
总结
在进入最终测试阶段时,首先写下合同规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合要求。 相比冗长的脚本,应优先选择小型且可测试的单元。当某个步骤失败时,故障应能指向单一的责任模块,而非复杂的流程链。 需为每次调用记录工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试过程将会浪费大量时间。
系列内容概览
在处理“The series so far”阶段时,首先需写下契约:所需的输入参数、成功信号以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 将此阶段视为输入与验证后输出之间的契约。为相关产物命名,明确成功判定标准,杜绝无声的半完成状态。 需记录每次调用的工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试过程将会浪费大量时间。 在处理“The series so far”阶段时,首先需写下契约:所需的输入参数、成功信号以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 应将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一处,以便操作人员无需查看整个系统结构即可进行审计。
本文中提到的FastMCP模式
在阶段测试中提到的FastMCP模式,若将其视为可度量的界面来处理效果最佳。在扩大范围之前,先记录一个成功的用例、一个失败案例以及回滚说明。 同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。 应提供具有明确结构规范和清晰副作用标识的工具。主机需要在自动批准之前知道哪些调用会改变状态。
MCP协议的演进
MCP协议的发展阶段若被视为可度量的对象,将会更易于管理。在扩大应用范围之前,应先记录一份理想的操作日志、一个故障案例以及回滚说明。
运营检查清单
将运营检查清单阶段视为可度量的对象,也能更高效地开展工作。在扩展范围之前,需先记录一份理想的操作日志、一个故障案例以及回滚说明。
在功能结果之外,还需记录执行时间以及令牌或查询的成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
为那些具有有限数据结构且带有明确副作用标签的工具提供接口。在自动批准之前,主机需要知道哪些调用会修改状态。
只要预算允许,就在持续集成过程中使用测试数据而非真实的付费 API 来执行关键路径的冒烟测试。
将配置信息与应用程序代码分开。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。
为那些具有有限数据结构且带有明确副作用标签的工具提供接口。在自动批准之前,主机需要知道哪些调用会修改状态。
在升级技术栈之前,先锁定各版本,为关键路径生成标准操作记录,并确认回滚步骤。共享环境需要设置速率限制、租户验证机制,以及明确的密钥轮换负责人。与其追求华丽的临时演示,不如注重扎实的可靠性。
关于528eef0765ac的批量处理说明:不要将提供者密钥放入代码仓库,为每个会话设置令牌使用上限,并将转录内容存储在评估用示例文件旁边,以便后续更换模型时仍能保持可比性。
强化措施的第0阶段若被视为可量化的评估标准,则效果最佳。在扩大范围之前,先收集一份理想的转录样本、一个失败案例以及回滚说明。将此阶段视为输入与经过验证的输出之间的契约,为相关文件命名,明确成功标准,杜绝无声的半完成状态。
强化措施细节0/869:针对此说明需测量处理耗时、错误类型以及令牌使用量,然后依据固定的评估标准而非主观判断来决定是否保留该变更。
在强化措施的第一阶段,应在修改代码之前明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。
强化措施细节 1/869:针对此措施需统计耗时、错误类型以及令牌使用情况,然后依据固定的评估标准而非主观判断来决定是否保留该变更。
在处理强化措施的第2阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合要求。 相比冗长的脚本,更应采用小型且可测试的单元。当某个步骤失败时,故障应能指向单一的责任模块,而非复杂的流程链。
强化措施细节2/869:需测量该步骤的运行时间、错误类型以及代币消耗情况,然后依据固定的评估标准而非主观判断来决定是否保留该修改。
将强化措施的第3阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的运行示例、一个失败案例以及回滚说明。 在功能结果旁同时记录时间消耗及代币或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外支出。
强化措施细节3/869:为该记录测量运行时间、错误类型以及令牌消耗情况,然后依据固定的问题集而非个别案例来决定是否保留该变更。
对于强化措施的第4阶段,在修改代码之前需明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新执行该步骤,而无需猜测隐藏状态。同时需将正常流程与故障恢复流程一并记录下来。重试机制、人工审核环节以及错误处理方式都是产品本身的组成部分,而非后续需要补充的内容。
强化措施细节4/869:为该记录测量运行时间、错误类型以及令牌消耗情况,然后依据固定的问题集而非个别案例来决定是否保留该变更。
在处理强化措施的第5阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合约定。 将这一阶段视为输入与验证后输出之间的契约。为相关产物命名,明确成功判定标准,杜绝默许的部分完成情况。
强化措施细节5/869:需测量该步骤的耗时、错误类型以及令牌消耗情况,然后依据固定的评估标准而非个人经验来决定是否保留该变更。
将强化措施的第6阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份标准操作示例、一个失败案例以及回滚说明。 应将配置信息与应用程序代码分开。环境文件、密钥存储和功能开关应集中存放于一处,以便操作人员无需查看全部代码结构即可进行审计。
强化措施细节6/869:测量该任务的执行时间、错误类型以及令牌消耗情况,然后依据固定的问题集而非个人经验来判断是否保留该变更。
对于强化措施的第7阶段,在修改代码之前需明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。相比复杂的脚本,更应采用小型且可测试的单元。当某一步骤失败时,故障原因应能指向具体的责任方,而非整个混乱的流程。
强化措施细节7/869:测量该任务的执行时间、错误类型以及令牌消耗情况,然后依据固定的问题集而非个人经验来判断是否保留该变更。
在处理强化建议的第8阶段时,首先写下相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合初始要求。
在功能结果旁记录执行时间以及令牌或查询成本。提前了解这些成本信息,可避免在系统从演示环境过渡到共享环境时出现意外费用。
强化建议的细节8/869要求:测量该建议对应的执行时间、错误类型以及令牌消耗情况,然后依据固定的评估标准而非个人经验来决定是否保留该修改。
将强化建议的第9阶段视为可度量的工作面来处理效果最佳。在扩大范围之前,先记录一个理想运行案例、一个失败案例以及回滚说明。
应同时记录正常流程和故障恢复流程。重试机制、人工审核环节以及错误处理方式都是产品本身的组成部分,而非后续需要补充的内容。
强化措施细节 9/869:记录该任务的执行时间、错误类型以及令牌消耗情况,然后依据固定的问题集而非个人经验来判断是否保留该变更。
在强化措施的第10阶段,应在修改代码之前明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。应将此阶段视为输入参数与验证后输出结果之间的契约,为相关成果命名、定义成功检测标准,并拒绝默许部分完成的情况。
强化措施细节 10/869:记录该任务的执行时间、错误类型以及令牌消耗情况,然后依据固定的问题集而非个人经验来判断是否保留该变更。
在处理强化措施的第11阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合要求。 应将配置信息与应用程序代码分开。环境文件、密钥存储以及功能开关应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。
强化措施细节11/869:需测量该措施的执行时间、错误类型以及令牌消耗情况,然后根据固定的评估标准而非个人经验来决定是否保留该修改。