当前位置: 首页 > news >正文

上下文工程实践 - 工具管理(上篇)

上下文工程实践 - 工具管理(上篇)

工具管理涉及的概念较多,所以我分成上下两篇来介绍:
上篇:主要讲 MCP 与 Tool 的定义和区别,以及工具的定义规范
下篇:继续展开,讨论工具的定位、错误处理方式和常见分类

1、什么是 MCP 和 Tool

在这里插入图片描述

  • MCP:是一份规范/协议,规定了“容器要怎么长、里面的功能要怎么描述、调用要怎么沟通”。就像 HTTP 规范本身,不是一个服务,而是大家都得遵守的语言。
  • MCP服务器:是规范的一个实现,它作为一个容器,可以对外暴露很多能力(Tool / Resource / Event)。就像一个跑在端口上的 Web 服务器,遵循 HTTP 协议,里面可以有很多 API。
  • Tool:是容器里的功能单元,一般表现为一个“函数”或者“接口”。调用的时候就是传参执行,返回结果。

Tool 目前使用起来是比较简单的,在项目中按照规范写一个函数,将这个函数以 tool 参数的形式传递给大模型,大模型输出函数名之后,系统调用该函数

如果你需要搭建一套工具集的服务,想要提供给多个项目使用,提供给别人使用,提供给支持 MCP 的客户端使用,那么你就可以遵守 MCP 协议搭建 MCP 的服务

我觉得 MCP 和 Tool 本质是差不多的,就是给模型提供“外部能力”的作用,根据自己的情况和能力来选择使用是比较好的

2、工具定义规范

在定义工具的时候,最重要的就是工具的描述和工具调用需要的参数

  1. 工具的描述清晰的工具描述可以提高大模型工具调用的成功率
  2. 工具的参数:描述参数工具的时候,要从参数名,参数类型,参数描述等尽可能多的方面讲这个参数表达的更清楚,这样在大模型输出工具参数的时候会准确和很多
  3. 工具的执行函数:这个是一个函数,用于大模型输出合适的工具调用指令之后,系统执行该函数

2.1、工具(Tool)的类型定义:

  • description🌟:工具的描述
  • parameters🌟(ToolParameterDefinition):工具的参数定义
  • category:工具分类
  • version:工具版本
  • handler:工具的执行函数,这个不需要传递给大模型,而是作为系统内部执行的
  • agentAccessible:控制工具是否对代理可见
  • internal:标记为内部工具类
  • Purpose:描述了工具的核心目的和功能定位,它回答”这个工具为什么存在“以及”它解决啦什么问题”,其是一个宏观的功能描述,例如:purpose: ‘Perform semantic search over stored memory entries to retrieve relevant knowledge and reasoning traces that can inform current decision-making.’
  • UseCase:描述了工具的具体使用场景和适用条件,它回答了“在什么情况下应该使用这个工具”以及“如何正确的使用这个工具”,其更多的关注应用场景和适用条件,例如:useCase: ‘Use when you need to find previously stored knowledge, code patterns, or technical information that may be relevant to answering current questions or solving problems.’

descriptionparamenters**handler**是工具定义必须要的参数,其他的参数是根据情况选择的

handler 是工具的执行函数,这个不用作为工具定义信息传递给大模型

2.2、工具参数(ToolParameterDefinition)的类型定义:

  • type:定义参数数据类型,如:'string' | 'number' | 'boolean' | 'object' | 'array'
  • description:提供参数的人类可读描述,帮助 LLM 理解参数的用途
  • minimum | maximum:定义参数数值的最小值和最大值
  • minItems | maxItems:定义数组参数的最小和最大元素数量
  • minLength | maxLength:定义字符串参数的最小和最大长度
  • oneOf:定义参数必须匹配多个 Schema 中的一个
  • additionalProperties:禁止对象参数包含额外属性
  • items:定义数组元素的类型
  • enum:定义参数的可能取值
  • default:定义参数的默认值

typedescription 是必须的,这个是参数定义的基本元素,并且参数命名也可以成为参数的描述

下面是一个工具定义完整的案例:

export const memoryOperationTool: InternalTool = {name: 'memory_operation',category: 'memory',internal: true,description:'Process extracted knowledge and determine memory operations (ADD, UPDATE, DELETE, NONE) using LLM-powered intelligent reasoning and similarity analysis with existing memories.',version: '2.0.0', // versionparameters: {type: 'object',properties: {extractedFacts: {type: 'array',description:'Array of knowledge facts already extracted from interactions, containing technical details, code patterns, or implementation information.',items: {type: 'string',},},existingMemories: {type: 'array',description: 'Array of existing memory entries to compare against for similarity analysis.',items: {type: 'object',properties: {id: {type: 'string',description: 'Unique identifier of the existing memory',},text: {type: 'string',description: 'Content of the existing memory',},metadata: {type: 'object',description: 'Optional metadata for the memory',},},required: ['id', 'text'],},},},required: ['extractedFacts'],},handler: memoryOperationHandler},
};//工具调用函数
const memoryOperationHandler = async (args: MemoryOperationArgs,context?: InternalToolContext
): Promise<MemoryOperationResult> => {// TODO: Implement intelligent reasoning logic to determine memory operations// Example placeholder return structurereturn {operations: [], // List of { operation: 'ADD' | 'UPDATE' | 'DELETE' | 'NONE', fact, memoryId? }};
};

2.3、工具执行函数定义

上面工具定义和工具参数定义这些都在作为 tool 参数传递给 LLM ,本质上就是 LLM 根据传递的工具描述和用户输入挑选出来一个合适的工具,但是大模型不负责执行工具函数,它只负责输出工具名称和工具参数

对于工具执行函数的定义,可以简单的根据工具参数去定义的,但是还是有一些常规定义方法,可以参考

工具的执行函数,会定义两个参数对象

  • arge:函数执行需要的参数对象
  • context |metadata:函数的元信息

一般来说,arge 是刚刚传入工具参数的类型,是工具执行函数的基本参数,而 context 或者 metadata 是属于辅助参数,大部分情况是用于监控和统计的,是可选的,没有这个也不影响函数的主功能执行

例如上面的定义案例中的memoryOperationHandler

//主要参数-参数对象
export interface MemoryOperationArgs {extractedFacts: string[];existingMemories?: {id: string;text: string;metadata?: Record<string, any>;}[];
}//辅助参数-元信息
export interface InternalToolContext {toolName: string;startTime: number;sessionId: string | undefined;userId?: string;metadata: Record<string, any> | undefined;// 服务依赖services?: {embeddingManager?: EmbeddingManager;vectorStoreManager?: VectorStoreManager;llmService?: ILLMService;knowledgeGraphManager?: KnowledgeGraphManager;};
}//工具执行函数
const memoryOperationHandler = async (args: MemoryOperationArgs,context?: InternalToolContext
): Promise<MemoryOperationResult> => {// TODO: Implement intelligent reasoning logic to determine memory operations// Example placeholder return structurereturn {operations: [], // List of { operation: 'ADD' | 'UPDATE' | 'DELETE' | 'NONE', fact, memoryId? }};
};

最后

本文节选自我正在整理的 「上下文工程实践」 项目,该项目已完整发布在 GitHub 上。
如果你希望相关的章节与案例,可以前往项目仓库查看:

👉 https://github.com/WakeUp-Jin/Practical-Guide-to-Context-Engineering


文章转载自:

http://U0EmxjL7.mxnhq.cn
http://gYSymFRh.mxnhq.cn
http://HNr0KOIz.mxnhq.cn
http://sgVQqeEP.mxnhq.cn
http://aRQkPCjR.mxnhq.cn
http://pH9rMA4m.mxnhq.cn
http://oARr2bnq.mxnhq.cn
http://8xacdBSZ.mxnhq.cn
http://MlkiS18N.mxnhq.cn
http://wSoxmy3n.mxnhq.cn
http://XxB4PIqH.mxnhq.cn
http://hK9cQ2kY.mxnhq.cn
http://YsvMpLCo.mxnhq.cn
http://cnry0due.mxnhq.cn
http://8TviYNBV.mxnhq.cn
http://kR83BZx4.mxnhq.cn
http://62bg7xJP.mxnhq.cn
http://FNrARqEi.mxnhq.cn
http://8fxCtBBx.mxnhq.cn
http://q76vCWDP.mxnhq.cn
http://8ThGNiSE.mxnhq.cn
http://hnbQClVl.mxnhq.cn
http://spqYvLtI.mxnhq.cn
http://CvjjkukX.mxnhq.cn
http://Uv0ttcdV.mxnhq.cn
http://p1yPUBg7.mxnhq.cn
http://zQxtoIok.mxnhq.cn
http://yqAcnx8S.mxnhq.cn
http://dZUvZXTh.mxnhq.cn
http://7nB0CWjC.mxnhq.cn
http://www.dtcms.com/a/383970.html

相关文章:

  • Spring Boot 项目瘦身实战
  • 【git基础】关于新仓库创建的几种方式
  • Dify 中的上下文变量以及它们与 system、user 变量的关系和配合方式
  • 【Android】可折叠式标题栏
  • Open cascade中如何使用BRepAlgoAPI_Splitter分割一个Face
  • JAVA开发知识合集6
  • 深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第十二章知识点问答(15题)
  • 条件表达式和逻辑表达式
  • 《数据密集型应用系统设计2》--数据复制与数据分片
  • 【C++】揭秘:虚函数与多态的实现原理
  • 项目交付后知识沉淀断档怎么办
  • Spring事务传播行为全解析
  • OpenCV一些进阶操作
  • Layer、LayUI
  • 机器视觉光源的尺寸该如何选型的方法
  • MySQL 高阶查询语句详解:排序、分组、子查询与视图
  • Mathtype公式批量编号一键设置公式居中编号右对齐
  • CKS-CN 考试知识点分享(5) 安全上下文 Container Security Context
  • 简单的分数求和 区分double和float
  • Python核心技术开发指南(066)——封装
  • SFR-DeepResearch: 单智能体RL完胜复杂多智能体架构
  • 【Docker+Nginx+Ollama】前后端分离式项目部署(传统打包方式)
  • ffplay数据读取线程
  • 回溯剪枝的 “减法艺术”:化解超时危机的 “救命稻草”(二)
  • 16-21、从监督学习到深度学习的完整认知地图——机器学习核心知识体系总结
  • 二叉树的顺序存储
  • 第7课:本地服务MCP化改造
  • CF607B Zuma -提高+/省选-
  • DMA-API(map和unmap)调用流程分析(十一)
  • LeetCode 1898.可移除字符的最大数目