[MCP] Sampling

news/2026/1/23 14:53:26/文章来源:https://www.cnblogs.com/Answer1215/p/19522356

Modern AI applications often need to generate new content (whether that's text, images, or more) on demand. This process is called sampling: asking a language model (or other generative model) to produce a completion or response based on a prompt and some context.

 

Your Sampling Request is a Prompt

When you make a sampling request, you're essentially crafting a prompt for the language model. The systemPrompt and messages you send become the instructions that guide the model's generation. This means that the quality and effectiveness of your sampling requests depend heavily on how well you structure your prompts.
Here are some key prompting tips for effective sampling:
  • Be specific and clear: Instead of "generate tags," try "generate 3-5 relevant tags for a journal entry about [topic], using lowercase words separated by commas"
  • Provide examples: Show the model what you want by including sample inputs and outputs in your prompt
  • Provide context: Include relevant information in your messages to help the model understand what you're asking for
  • Set expectations: Use the system prompt to establish the model's role and the format you expect
  • Test and iterate: Start with simple prompts and refine them based on the results you get
  • Consider safety: Structure your prompts to avoid generating harmful or inappropriate content
For more advanced prompting techniques and research-backed strategies, see The Prompt Report, a comprehensive survey of 58 LLM prompting techniques and best practices for modern AI systems.
MCP standardizes how servers and clients can request these generations. Instead of requiring every server to manage its own API keys and model integrations, MCP lets servers request completions through a client, which handles model selection, permissions, and user controls. This approach enables powerful agentic behaviors—like having an LLM suggest tags for a journal entry, or generate a summary for a document—while keeping the user in control (and it lets you take advantage of the model for which your user is already paying).
In this exercise, you'll extend your MCP server to leverage the sampling capability. You'll see how to:
  • Request a model completion from the client, including setting a system prompt, user messages, and token limits.
  • Parse and validate the model's response.
  • Use sampling to automate tasks in your application, such as suggesting tags for new journal entries.
  • Send log messages from your server to the client for debugging and monitoring.
You'll also explore how to craft effective prompts for the model, and how to structure your requests and responses for reliability and safety.

Server-Side Logging

As part of this exercise, you'll also learn about MCP's logging capabilities. The sendLoggingMessage function allows your server to send log messages to the client, which can be useful for:
  • Debugging: Send information about what your server is doing
  • Monitoring: Track the flow of requests and responses
  • User feedback: Provide insights into the sampling process
Log messages can have different levels (error, debug, info, notice, warning, critical, alert, emergency) and can include any JSON-serializable data.
 
  • 📜 MCP Sampling Spec
  • 📜 MCP Logging Documentation
  • 📜 Goose Blog: MCP Sampling: When Your Tools Need to Think

 

Sample Code:

import { invariant } from '@epic-web/invariant'
import { z } from 'zod'
import { type EpicMeMCP } from './index.ts'const resultSchema = z.object({content: z.object({type: z.literal('text'),text: z.string(),}),
})export async function suggestTagsSampling(agent: EpicMeMCP, entryId: number) {const clientCapabilities = agent.server.server.getClientCapabilities()if (!clientCapabilities?.sampling) {console.error('Client does not support sampling, skipping sampling request')return}const entry = await agent.db.getEntry(entryId)invariant(entry, `Entry with ID "${entryId}" not found`)const existingTags = await agent.db.getTags()const currentTags = await agent.db.getEntryTags(entry.id)const result = await agent.server.server.createMessage({systemPrompt: `
You are a helpful assistant that suggests relevant tags for journal entries to make them easier to categorize and find later.
You will be provided with a journal entry, it's current tags, and all existing tags.
Only suggest tags that are not already applied to this entry.
Journal entries should not have more than 4-5 tags and it's perfectly fine to not have any tags at all.
Feel free to suggest new tags that are not currently in the database and they will be created.You will respond with JSON only.
Example responses:
If you have no suggestions, respond with an empty array:
[]If you have some suggestions, respond with an array of tag objects. Existing tags have an "id" property, new tags have a "name" and "description" property:
[{"id": 1}, {"name": "New Tag", "description": "The description of the new tag"}, {"id": 24}]`.trim(),messages: [{role: 'user',content: {type: 'text',mimeType: 'application/json',text: JSON.stringify({ entry, currentTags, existingTags }),},},],maxTokens: 100,})const parsedResult = resultSchema.parse(result)const { idsToAdd } = await parseAndProcessTagSuggestions({agent,modelResponse: parsedResult.content.text,existingTags,currentTags,}).catch((error) => {console.error('Error parsing tag suggestions', error)void agent.server.server.sendLoggingMessage({level: 'error',data: {message: 'Error parsing tag suggestions',modelResponse: parsedResult.content.text,error,},})throw error})for (const tagId of idsToAdd) {await agent.db.addTagToEntry({entryId: entry.id,tagId,})}const allTags = await agent.db.listTags()const updatedEntry = await agent.db.getEntry(entry.id)const addedTags = Array.from(idsToAdd).map((id) => allTags.find((t) => t.id === id)).filter(Boolean)void agent.server.server.sendLoggingMessage({level: 'info',logger: 'tag-generator',data: {message: 'Added tags to entry',addedTags,entry: updatedEntry,},})
}const existingTagSchema = z.object({ id: z.number() })
const newTagSchema = z.object({name: z.string(),description: z.string().optional(),
})type ExistingSuggestedTag = z.infer<typeof existingTagSchema>
type NewSuggestedTag = z.infer<typeof newTagSchema>
type SuggestedTag = ExistingSuggestedTag | NewSuggestedTagfunction isExistingTagSuggestion(tag: SuggestedTag,existingTags: Array<{ id: number; name: string }>,currentTags: Array<{ id: number; name: string }>,
): tag is ExistingSuggestedTag {return ('id' in tag &&existingTags.some((t) => t.id === tag.id) &&!currentTags.some((t) => t.id === tag.id))
}function isNewTagSuggestion(tag: SuggestedTag,existingTags: Array<{ id: number; name: string }>,
): tag is NewSuggestedTag {return 'name' in tag && existingTags.every((t) => t.name !== tag.name)
}async function parseAndProcessTagSuggestions({agent,modelResponse,existingTags,currentTags,
}: {agent: EpicMeMCPmodelResponse: stringexistingTags: Array<{ id: number; name: string }>currentTags: Array<{ id: number; name: string }>
}) {const responseSchema = z.array(z.union([existingTagSchema, newTagSchema]))const suggestedTags = responseSchema.parse(JSON.parse(modelResponse))// First, resolve any name-based suggestions that match existing tags to their IDsconst resolvedTags: Array<SuggestedTag> = []for (const tag of suggestedTags) {if ('name' in tag) {const existingTag = existingTags.find((t) => t.name === tag.name)if (existingTag) {resolvedTags.push({ id: existingTag.id })continue}}resolvedTags.push(tag)}const suggestedNewTags = resolvedTags.filter((tag) =>isNewTagSuggestion(tag, existingTags),)const suggestedExistingTags = resolvedTags.filter((tag) =>isExistingTagSuggestion(tag, existingTags, currentTags),)const idsToAdd = new Set<number>(suggestedExistingTags.map((t) => t.id))if (suggestedNewTags.length > 0) {for (const tag of suggestedNewTags) {const newTag = await agent.db.createTag(tag)idsToAdd.add(newTag.id)}}return { idsToAdd, suggestedNewTags, suggestedExistingTags }
}

 

Usage:

	agent.server.registerTool('create_entry',{title: 'Create Entry',description: 'Create a new journal entry',annotations: {destructiveHint: false,openWorldHint: false,} satisfies ToolAnnotations,inputSchema: createEntryInputSchema,outputSchema: { entry: entryWithTagsSchema },},async (entry) => {const createdEntry = await agent.db.createEntry(entry)if (entry.tags) {for (const tagId of entry.tags) {await agent.db.addTagToEntry({entryId: createdEntry.id,tagId,})}}void suggestTagsSampling(agent, createdEntry.id)const structuredContent = { entry: createdEntry }return {structuredContent,content: [createText(`Entry "${createdEntry.title}" created successfully with ID "${createdEntry.id}"`,),createEntryResourceLink(createdEntry),createText(structuredContent),],}},)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1205333.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026年卖家精灵折扣码是什么 卖家精灵是干嘛用的

2026年卖家精灵折扣码是什么 卖家精灵是干嘛用的卖家精灵(SellerSprite)提供一站式选品、市场分析、关键词优化、产品监控等软件工具,精准查询每个亚马逊产品的销量、关键词、自然搜索数据,帮助亚马逊卖家验证选品…

2026全国雅思培训机构深度测评TOP5 | 权威榜单,精准选课不踩坑

据雅思官方统计,每年全国数十万考生投身雅思培训,其中超六成面临选课迷茫、提分困难、缺乏权威测评方案等核心痛点,尤其是在北京朝阳区、上海静安区、广州天河区、深圳南山区、成都锦江区等城市区县,考生对靠谱、高…

Postman接口测试自学指南

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、前言 之前还没实际做过接口测试的时候呢&#xff0c;对接口测试这个概念比较渺茫&#xff0c;只能靠百度&#xff0c;查看各种接口实例&#xff0c;然后…

京东e卡回收98折实测:揭秘压低折扣的秘密

朋友收到公司发放的大额京东E卡,因极少在京东消费,便想将其变现。网上诸多“京东E卡回收98折”的广告令他心动,这般高折扣意味着能拿回绝大部分卡内金额。怀着高回报期待,他尝试对接回收平台,却意外陷入虚假宣传的…

聊聊整村统建的发展趋势,金鼎乡建创新模式促升级

本榜单依托全维度市场调研与真实乡村建设行业口碑,深度筛选出五家标杆企业,为有整村统建需求的村集体、乡镇政府及村民群体提供客观依据,助力精准匹配适配的专业服务伙伴。 TOP1 推荐:宁波金鼎乡建科技有限公司 推…

索引

二、索引分类 1、主键索引 (primary key/pri) 一个表中只能由有一个,不能为空,唯一 添加主键: ALTER table 表名add PRIMARY key(字段名) 如: ALTER table 表名add PRIMARY key(id) 2、唯一索引 (unique /uni) …

2026国内最新天丝面料厂商top10推荐!广东广州等地优质天丝面料品牌权威榜单发布,资质服务双优助力高品质纺织

随着消费升级与可持续时尚理念的深入发展,天丝面料以其天然环保、舒适透气的卓越特性,成为纺织服装行业的核心原材料之一。据中国纺织工业联合会最新行业报告显示,2025年国内天丝面料市场需求量同比增长35%,但行业…

智能化照明革命:升降照明灯行业领先企业生产商选购建议

智能化照明革命:升降照明灯行业领先企业生产商选购建议 一、升降照明灯行业背景与发展趋势 升降照明灯作为一种可灵活调节照射高度、覆盖范围的特种照明设备,核心应用于道路抢修、消防救援、防汛抢险、户外施工、大型…

失蜡铸造2026新动态:这些企业为何成为焦点?精密铸造/失蜡铸造/硅溶胶铸造/硅溶胶精密铸造,失蜡铸造工厂推荐榜单

在制造业蓬勃发展的当下,失蜡铸造作为一项古老而又先进的工艺,正焕发着新的生机。随着科技的不断进步和市场需求的日益多样化,失蜡铸造行业面临着新的机遇与挑战。一方面,高端制造业对失蜡铸造产品的精度、质量和定…

2026便利店与高奢酒店智能咖啡机优选方案:全场景智能咖啡设备解析

在2026年商业咖啡场景中,便利店追求高效稳定的出杯能力,高奢酒店则看重品质一致性与体验感,两者对智能咖啡机的核心需求虽有差异,但都离不开技术与场景的深度适配。CAYE咖爷科技作为专注自主研发的商用咖啡设备企业…

软件测试用例的设计详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、测试用例的概念软件测试人员向被测试系统提供的一组数据的集合&#xff0c;包括 测试环境、测试步骤、测试数据、预期结果2、为什么在测试前要设计测试用例测…

2026年高剪切乳化机/搅拌罐/单效浓缩器/蒸馏器/反应釜行业首选推荐:温州超创机械科技有限公司

开篇引言:从某药企选型困境看行业变革压力 2025年12月,某国内Top10生物制药企业因新药研发需求,紧急采购高剪切乳化机用于疫苗佐剂制备。然而,在选型过程中,企业发现市场主流设备存在三大痛点:卫生级设计不足导致…

2026年压延机优质供应商排名,南通金轮精密技术实力获认可

在金属线材加工产业升级的浪潮中,一台性能稳定、精度可靠的压延机是制造企业突破产能瓶颈、保障产品品质的核心引擎,关乎产线效率与市场竞争力。面对市场上良莠不齐的压延机供应商,如何精准抉择?以下结合行业需求与…

京东e卡回收一般几折?2026最新价格表一览!

京东e卡回收一般几折?2026最新价格表一览!最近后台总被问:“京东e卡回收一般几折?”作为卡券回收圈的“老江湖”,我必须说——2026年的京东e卡回收市场,折扣波动比往年更“有看头”!从50元小额卡到5000元大额卡…

2026年行业内专业的保温装饰一体化板厂商联系电话,聚氨酯保温装饰一体板,保温装饰一体化板加工厂联系方式

随着建筑节能标准的不断提升与建筑外立面美学需求的日益增长,保温装饰一体化板作为集保温、装饰、防火等功能于一体的高效建材,其市场应用愈发广泛。然而,面对市场上品牌众多、品质参差不齐的现状,如何甄别并选择一…

2026年环保认证车充外壳厂家排名情况如何

在汽车后市场与消费电子融合的赛道上,车充外壳作为车载充电设备的第一道门面,不仅承载着保护内部电路的基础功能,更关乎品牌辨识度与用户安全体验。面对市场上良莠不齐的供应商,如何找到口碑好的车充外壳推荐厂家?…

东方博宜OJ 2390:区间修改与查询 ← 线段树

​【题目来源】https://oj.czos.cn/p/2390【题目描述】给定由 N 个整数构成的数列,再给定 M 条指令,每条指令可能是如下两种之一:1. C l r d,表示将区间 [l,r] 之间的每个数都加上整数 d;2. Q l r,表示询问区间 …

2026年戈登计TOP5:生产、定制与综合服务能力全景评估

戈登计(热流计)作为测量热流密度的核心传感器,其精度与可靠性是航空航天热防护系统验证、发动机燃烧室测试、高超声速飞行器研制及材料热物性研究等领域的关键技术基石。随着全球对能源效率、热管理与极端环境测试需…

2026大型企业办公室全自动咖啡机推荐:赋能商务场景高效咖啡体验

在2026年的大型企业办公场景中,高效、稳定且品质出众的全自动咖啡机已成为商务接待、员工福利的重要配置。无论是茶水间日常补给、会议室商务洽谈,还是接待区高端服务,都需要一台能兼顾口感一致性、操作便捷性与维护…

安庆MNS2.0低压开关柜实力制造企业,哪家性价比高?

2026年工业数字化转型加速深化,低压配电系统作为工业生产、基础设施运行的动力中枢,其可靠性、智能化水平直接决定企业生产连续性与能源效率。无论是工业自动化场景下的精准配电需求,还是基础设施领域的长周期稳定运…