从零到一:基于上下文工程的 Agent 后端设计
前言
从之前我整理的上下文工程实践指南出发,我大概梳理出来,在一个 Agent 中最核心的模块我分为四类:
- 工具模块和管理:定义一些 Agent 的工具,可以是 MCP,也可以是 Skill,除了定义之后,我们还需要管理:工具的输出裁剪,工具的执行审核流程等
- 上下文管理:这个是启动 Agent 的关键,整理好注入给 LLM 的上下文是完成任务的关键,其中重要的是:上下文的压缩、上下文的裁剪等,同时 Agent 上下文会遇到:上下文污染、上下文干扰、上下文冲突、上下文混淆的问题,这些问题需要开发者结合系统工程的方式来解决
- LLM 模块:这个是 Agent 真正的核心,就像钢铁侠的“方舟反应堆”一样
- Agent 形态(执行器):这个是 Agent 的执行形态,目前可以是工作流、可以是单智能体、可以是多智能体等各种形态
上下文工程实践指南 仓库名字:Practical-Guide-to-Context-Engineering
仓库链接:github.com/WakeUp-Jin/…
🪐 借助这四点核心的思路,我构建了一套 Agent 后端架构方案,为了方便大家理解,我还开发了一个 CLI 脚手架工具,可以一键安装模板项目进行预览查看
主要是让大家查看代码文件和文件之间的结构,以此对借助上下文工程的思路开发一个 Agent 有更清晰的感觉
cli 项目链接:github.com/WakeUp-Jin/…
启动命令:
npm create context-template
一、总设计
整个后端架构设计中,是按照上下文工程来做的设计,上下文管理是核心,它就是一个完整的大输入,以此输入作为前提,来解决用户的问题
- LLM 模块:是使用 openaiSDK 来实现的多种型号模型的使用,这里是提供模型的
- 工具模块和管理:工具是 LLM 关键的外部能力,是结合到上下文来让 LLM 使用的
- 上下文管理:这个是统一的上下文,其负责编排好上下文,在 执行器中将上下文输入给 LLM,以 LLM 的输出来解决问题
二、LLM 模块
关于 LLM 模块,整个模块的分为:
- LLM 创建工厂函数:根据传入的参数来判断实例化哪一个 LLM 服务类
- LLM 服务类:要编写一个相应的 LLM 服务类,里面有三种方法:complete 方法、simpleChat 方法、generate 方法,其中最重要的是 complete 方法,这个会作为上下文输入的核心方法
目录情况结构:
- llm
- services
- DeepSeekService.ts // 这个就是具体的LLM服务类
- DoubaoService.ts
- utils
- types
- index.ts //这个是整个llm模块的类型约束
- factory.ts //LLM工厂函数
- index.ts
举一个例子:
//具体使用
//1、使用工厂函数实例化相应的LLM类
const service = await createLLMService({
provider: 'deepseek',
model: 'deepseek-chat',
apiKey: process.env.DEEPSEEK_API_KEY || 'your-api-key-here',
maxIterations: 5,
});
//2、调用simpleChat方法
const answer = await service.simpleChat(
'用一句话解释什么是大语言模型?',
'你是一个有帮助的 AI 助手'
);
//3、调用complete方法
let message=[//...]
let tools=[//...]
const response=await service.complete(message,tools)
参考文档在上下文工作实践指南中:
- LLM模块-服务层的设计文档
三、工具模块和管理
工具模块主要的三个点就是:
- 工具的定义:定义一个工具对象需要哪些属性
- 提供给 LLM 工具参数:可以是 tools 参数,也可以是提示词文本
- 工具的执行函数:工具的执行函数
目录结构:
- tool
- FileReadTool
- FileReadTool.ts //工具定义
- prompt.ts //工具描述
- GrepTool
- GrepTool.ts
- prompt.ts
- index.ts
- ToolManager.ts //工具管理函数
- types.ts //工具模块的类型
1、 工具定义
/**
* 工具定义基础接口
*/
export interface InternalTool<TArgs = any, TResult = any> {
/** 工具名称(唯一标识) */
name: string;
/** 工具分类(如 filesystem、search、network) */
category: string;
/** 是否为内部工具 */
internal: boolean;
/** 工具描述(简短,详细描述在 prompt 中) */
description: string;
/** 版本号 */
version: string;
/** 参数定义(JSON Schema 格式) */
parameters: ToolParameterSchema;
/** 工具处理函数 */
handler: (args: TArgs, context?: InternalToolContext) => Promise<TResult>;
/** 可选:格式化结果给 AI */
renderResultForAssistant?: (result: TResult) => string;
/** 可选:权限控制 */
needsPermissions?: (input?: TArgs) => boolean; // 是否需要权限
isEnabled?: () => Promise<boolean>; // 是否启用
isReadOnly?: () => boolean; // 是否只读
isConcurrencySafe?: () => boolean; // 是否并发安全
}
例如:
//1、创建工具管理器
const toolManager = new ToolManager();
//2、获取工具定义
const tools = toolManager.getTools();
//3、创建LLM服务
const llm = await createLLMService(
{
provider: 'deepseek',
model: 'deepseek-chat',
apiKey: config.apiKey || '',
maxIterations: 5,
},
tools
);
//4、调用工具执行函数
const answer = await llm.generate(
'请帮我读取 package.json 文件,并告诉我项目名称是什么'
);
参考文档在上下文工作实践指南中:
- 工具模块-工具管理(下篇):mp.weixin.qq.com/s/1iv_4Jyp3…
- 工具模块-工具管理(上篇):mp.weixin.qq.com/s/sIrbB4WXM…
四、上下文管理
在这种上下文管理设计中,将该 Agent 中所有种类的上下文管理统一起来,让 LLM 只需要直接和上下文输入联系
🌟🌟 在这种开发模式下,开发的重心在上下文的获取和整理,但是应用的关键核心是 LLM。
- 保证核心是 LLM,后续就可以根据模型能力的提升,Agent 的效果也变得越来越好。
- 开发重心是上下文,可以极大的发挥应用开发者的能力和创造力
目录结构:
- context
- base
- BaseContext.ts //基础上下文类
- modules
- ConversationContext.ts //上下文 - 会话历史记录类
- MemoryContext.ts //上下文 - 用户记忆类
- StructuredOutputContext.ts //上下文 - 结构化输出类
- SystemPromptContext.ts //上下文 - 系统提示词类
- ToolContext.ts //上下文 - 工具管理类
- ContextManager.ts //上下文管理器
- index.ts
- types.ts // 上下文管理模块的类型约束
参考文档在上下文工作实践指南中:
- 上下文管理模块:mp.weixin.qq.com/s/Lym4JsCFM…
- 上下文管理模块-上下文压缩:ClaudeCode、Gemini与工具消息裁剪:mp.weixin.qq.com/s/waJdBPTk6…
五、执行器
关于执行器的详细文档在上下文工程实践指南中:
- Agent形态-智能体系统构建策略-单智能体和多智能体:mp.weixin.qq.com/s/CkqpUBczm…
- Agent形态-两种世界的交互形态:协同Agent与自主Agent :mp.weixin.qq.com/s/TcO7DLLq8…