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

- MCP :是一份规范/协议,规定了"容器要怎么长、里面的功能要怎么描述、调用要怎么沟通"。就像 HTTP 规范本身,不是一个服务,而是大家都得遵守的语言。
- MCP服务器 :是规范的一个实现,它作为一个容器,可以对外暴露很多能力(Tool / Resource / Event)。就像一个跑在端口上的 Web 服务器,遵循 HTTP 协议,里面可以有很多 API。
- Tool :是容器里的功能单元,一般表现为一个"函数"或者"接口"。调用的时候就是传参执行,返回结果。
Tool 目前使用起来是比较简单的,在项目中按照规范写一个函数,将这个函数以 tool 参数的形式传递给大模型,大模型输出函数名之后,系统调用该函数
如果你需要搭建一套工具集的服务,想要提供给多个项目使用,提供给别人使用,提供给支持 MCP 的客户端使用,那么你就可以遵守 MCP 协议搭建 MCP 的服务
我觉得 MCP 和 Tool 本质是差不多的,就是给模型提供"外部能力"的作用,根据自己的情况和能力来选择使用是比较好的
2、工具定义规范
在定义工具的时候,最重要的就是工具的描述和工具调用需要的参数
- **工具的描述:**清晰的工具描述可以提高大模型工具调用的成功率
- **工具的参数:**描述参数工具的时候,要从参数名,参数类型,参数描述等尽可能多的方面讲这个参数表达的更清楚,这样在大模型输出工具参数的时候会准确和很多
- **工具的执行函数:**这个是一个函数,用于大模型输出合适的工具调用指令之后,系统执行该函数
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.'
description
和paramenters
、**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:定义参数的默认值
type
和description
是必须的,这个是参数定义的基本元素,并且参数命名也可以成为参数的描述
下面是一个工具定义完整的案例:
typescript
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', // version
parameters: {
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 structure
return {
operations: [], // List of { operation: 'ADD' | 'UPDATE' | 'DELETE' | 'NONE', fact, memoryId? }
};
};
2.3、工具执行函数定义
上面工具定义和工具参数定义这些都在作为 tool 参数传递给 LLM ,本质上就是 LLM 根据传递的工具描述和用户输入挑选出来一个合适的工具,但是大模型不负责执行工具函数,它只负责输出工具名称和工具参数
对于工具执行函数的定义,可以简单的根据工具参数去定义的,但是还是有一些常规定义方法,可以参考
工具的执行函数,会定义两个参数对象
- arge:函数执行需要的参数对象
- context |metadata:函数的元信息
一般来说,arge 是刚刚传入工具参数的类型,是工具执行函数的基本参数,而 context 或者 metadata 是属于辅助参数,大部分情况是用于监控和统计的,是可选的,没有这个也不影响函数的主功能执行
例如上面的定义案例中的memoryOperationHandler
:
typescript
//主要参数-参数对象
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 structure
return {
operations: [], // List of { operation: 'ADD' | 'UPDATE' | 'DELETE' | 'NONE', fact, memoryId? }
};
};
最后
本文节选自我正在整理的 「上下文工程实践」 项目,该项目已完整发布在 GitHub 上。
如果你希望阅读更多相关的章节与案例,可以前往项目仓库查看: