全栈AI实战:基于 TypeScript + LangChain + MCP 的企业级智能研发助手

(含 Skill 体系 / 插件机制 / Agent Harness 完整工程实现)
一、项目背景与核心目标
1.1 行业痛点
在中大型研发团队中,研发流程横跨需求、编码、测试、部署、运维多个环节,依赖 Git 代码库、Jira 需求管理、MySQL 业务数据库、ELK 日志平台、Swagger 接口文档、内部 Wiki 等十余套系统。开发人员排查一个线上问题,往往需要在 5+ 平台间切换查询信息,新人上手需要花费数周熟悉各类内部系统;同时,团队内部零散的 AI 工具(代码补全、文档问答、SQL生成)各自独立,无法共享上下文,也难以针对业务场景定制扩展,能力复用率极低。
现有 AI 助手普遍存在三个核心问题:
-
工具接入成本高:每对接一个内部系统都要单独开发工具函数,接口不统一,跨模型无法复用
-
能力扩展性差:业务场景的 AI 能力硬编码在项目中,第三方团队无法快速贡献能力
-
执行不可控:AI Agent 执行过程黑盒,缺少超时熔断、安全管控、效果评测机制,难以落地到生产级企业场景
1.2 项目定位
本项目 DevPilot AI 是一套面向研发团队的统一智能研发助手中台,以 TypeScript 为全栈开发语言,打造「标准协议接入 + 场景化技能 + 动态插件扩展 + 可控运行时」的完整 AI 应用架构。最终实现一个入口覆盖代码审查、故障排查、文档问答、数据查询、接口调试等多个研发场景,支持团队按需扩展能力、沉淀研发知识库的企业级全栈 AI 系统。
1.3 核心技术目标
• 基于 MCP (Model Context Protocol) 实现所有外部工具与数据源的标准化接入,一次开发多模型复用
• 基于 LangChain.js 构建可编排的 Skill 技能体系,封装面向业务场景的复合 AI 能力
• 设计动态插件系统,支持第三方团队按规范开发、热加载能力插件
• 实现 Agent Harness 运行时,提供任务调度、超时熔断、安全管控、全链路追踪、效果评测能力
• 全栈 TypeScript 落地,前后端类型共享,工程化规范完整,可直接用于生产环境二次开发
二、整体架构与技术选型
2.1 系统分层架构
┌─────────────────────────────────────────────────────┐
│ 前端交互层 (React) │
│ 对话界面 | 技能市场 | 插件管理 | 执行链路可视化 │
├─────────────────────────────────────────────────────┤
│ 后端服务层 (NestJS) │
│ 鉴权网关 | 会话管理 | SSE流式输出 | 插件管控 │
├─────────────────────────────────────────────────────┤
│ AI 引擎核心层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Skill │ │ LangChain│ │ Agent Harness │ │
│ │ 引擎 │ │ 编排层 │ │ 运行时管控 │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
│ ┌──────────────────────────────────────────────┐ │
│ │ MCP 适配层 (工具标准化接入) │ │
│ └──────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────┤
│ 工具与数据层 │
│ MCP工具服务 | 插件沙箱 | 向量库 | 业务数据库 │
└─────────────────────────────────────────────────────┘
2.2 全栈技术栈清单
层级 技术选型 说明
前端 React 18 + TypeScript 5 + Vite 5 主框架,全链路类型安全
前端 Ant Design 5 + Zustand UI 组件库 + 轻量状态管理
前端 @microsoft/fetch-event-source + react-markdown SSE 流式渲染 + Markdown 内容展示
后端 NestJS 10 + TypeScript 企业级 Node 后端框架,依赖注入 + 模块化
后端 Prisma ORM + MySQL + Redis 数据持久化 + 会话缓存
AI核心 LangChain.js 0.3 + @langchain/openai Agent 编排、RAG、工具调用框架
AI核心 @modelcontextprotocol/sdk MCP 协议官方 SDK,工具标准化接入
AI核心 自研 Agent Harness AI 任务运行时,管控 + 评测 + 追踪
基础设施 Docker + Docker Compose + LangSmith 容器化部署 + AI 调试评测
2.3 核心概念对齐
• MCP:Anthropic 推出的模型上下文协议,是 AI 与外部工具交互的通用标准。本项目中所有内部系统都以 MCP 服务形式暴露,实现一次接入、多模型多 Agent 复用。
• Skill:面向业务场景的 AI 能力封装,是比单工具更高层级的能力单元。例如「线上故障排查 Skill」会自动串联日志查询、数据库查数据、Git 查提交记录,按固定分析流程输出结论。
• 插件:第三方扩展包,遵循统一规范,可自定义 Skill、注册 MCP 工具、扩展前端 UI,支持热加载,是平台能力开放的核心。
• Agent Harness:AI 任务的运行容器,相当于 Agent 的「操作系统」。包裹在 LangChain Agent 外层,提供生命周期管理、超时熔断、安全拦截、链路追踪、效果评测等生产级能力。
三、核心模块实战实现
3.1 工程初始化:全栈 TS 项目骨架
采用 Monorepo 架构管理前后端与共享类型,使用 pnpm workspace 组织项目。
目录结构
devpilot-ai/
├── packages/
│ ├── frontend/ # React 前端
│ ├── backend/ # NestJS 后端
│ ├── shared-types/ # 前后端共享类型定义
│ ├── ai-core/ # AI 核心:Skill/Harness/MCP 适配
│ └── plugins-sdk/ # 插件开发 SDK
├── docker-compose.yml
└── package.json
共享类型定义(packages/shared-types)
// 会话消息类型
export interface ChatMessage {
id: string;
role: 'user' | 'assistant' | 'tool';
content: string;
timestamp: number;
toolCalls?: ToolCallRecord\[\];
}
// Skill 元信息
export interface SkillMeta {
id: string;
name: string;
description: string;
icon: string;
category: string;
author: string;
}
// 插件元信息
export interface PluginMeta {
id: string;
name: string;
version: string;
skills: string\[\];
mcpServers: string\[\];
}
3.2 MCP 层:标准化工具接入实战
MCP 是整个项目的工具接入底座,我们不直接在 LangChain 中硬编码工具函数,而是将所有外部能力封装为独立的 MCP 服务,AI 引擎通过 MCP 客户端统一调用。
步骤1:实现数据库查询 MCP 服务
// packages/mcp-servers/src/mysql-server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const server = new Server(
{ name: 'devpilot-mysql', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
// 注册工具列表
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'query_business_data',
description: '执行只读 SQL 查询业务数据,仅支持 SELECT 语句',
inputSchema: {
type: 'object',
properties: { sql: { type: 'string', description: 'SQL 查询语句' } },
required: 'sql'
}
}
]
}));
// 工具执行逻辑
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === 'query_business_data') {
// 安全校验:只允许 SELECT 语句
if (!args.sql.trim().toLowerCase().startsWith('select')) {
return { content: { type: 'text', text: '仅允许执行 SELECT 查询语句' }, isError: true };
}
try {
const result = await prisma.$queryRawUnsafe(args.sql);
return { content: { type: 'text', text: JSON.stringify(result, null, 2) } };
} catch (e) {
return { content: { type: 'text', text: `SQL执行失败: ${e.message}` }, isError: true };
}
}
return { content: { type: 'text', text: '未知工具' }, isError: true };
});
// 启动服务
const transport = new StdioServerTransport();
await server.connect(transport);
步骤2:LangChain 集成 MCP 工具
在 AI 核心层封装 MCP 工具适配器,将 MCP 工具自动转换为 LangChain 可识别的 Tool 类型:
// packages/ai-core/src/mcp/mcp-adapter.ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
export class McpToolAdapter {
private client: Client;
constructor(serverCommand: string, serverArgs: string\[\]) {
const transport = new StdioClientTransport({ command: serverCommand, args: serverArgs });
this.client = new Client({ name: 'devpilot-agent', version: '1.0.0' }, { capabilities: {} });
this.client.connect(transport);
}
// 批量获取 MCP 工具并转换为 LangChain Tool
async getLangChainTools() {
const { tools } = await this.client.listTools();
return tools.map(mcpTool => {
const schema = z.object(mcpTool.inputSchema.properties as any);
return tool(
async (args) => {
const result = await this.client.callTool({ name: mcpTool.name, arguments: args });
return result.content.map(c => c.text).join('\n');
},
{
name: mcpTool.name,
description: mcpTool.description,
schema
}
);
});
}
}
3.3 Skill 体系:基于 LangChain 的业务能力封装
Skill 是业务场景的核心载体,分为基础 Skill(单能力)和复合 Skill(多工具编排)。我们设计统一的 Skill 基类,所有 Skill 遵循相同的生命周期。
Skill 基类定义
// packages/ai-core/src/skills/base-skill.ts
import { BaseMessage } from '@langchain/core/messages';
import { AgentHarness } from '.../harness/agent-harness';
export abstract class BaseSkill {
abstract id: string;
abstract name: string;
abstract description: string;
abstract category: string;
// 技能匹配度检测,用于自动路由
abstract matchIntent(userQuery: string, context: any): Promise;
// 技能执行入口,由 Harness 调度
abstract execute(
userQuery: string,
chatHistory: BaseMessage\[\],
harness: AgentHarness
): Promise<AsyncIterable>;
}
实战:实现「线上故障排查」复合 Skill
该 Skill 自动串联日志查询、数据库查询、Git 提交记录三个 MCP 工具,按排障流程逐步分析,输出根因与解决方案。
// packages/ai-core/src/skills/troubleshoot-skill.ts
import { BaseSkill } from './base-skill';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { ChatOpenAI } from '@langchain/openai';
import { AgentHarness } from '.../harness/agent-harness';
import { McpToolAdapter } from '.../mcp/mcp-adapter';
export class TroubleshootSkill extends BaseSkill {
id = 'troubleshoot';
name = '线上故障排查';
description = '针对线上接口报错、服务异常,自动排查日志、数据库、代码提交,定位根因';
category = '运维排障';
async matchIntent(userQuery: string): Promise {
const keywords = '报错', '故障', '异常', '500', '502', '接口失败', '线上问题';
const hit = keywords.some(k => userQuery.includes(k));
return hit ? 0.9 : 0.2;
}
async execute(userQuery: string, chatHistory: any\[\], harness: AgentHarness) {
// 从 Harness 获取可用的 MCP 工具
const tools = await harness.getAvailableTools('mysql', 'elk-log', 'git');
const llm = new ChatOpenAI({ model: 'gpt-4o', temperature: 0.1 });
const agent = createReactAgent({ llm, tools });
const systemPrompt = `
你是资深研发运维专家,负责线上故障排查。请严格遵循以下流程:
1. 先调用日志工具查询对应时间段的错误日志
2. 根据错误信息调用数据库工具查询相关业务数据
3. 调用 Git 工具查询最近的代码提交记录
4. 综合所有信息输出根因分析、影响范围、修复建议
每一步操作都要向用户说明当前在做什么。
`;
const stream = await agent.stream({
messages: [...chatHistory, { role: 'user', content: userQuery }],
systemMessage: systemPrompt
});
// 转换为流式输出,同时上报 Harness 做链路追踪
return async function* () {
for await (const chunk of stream) {
if (chunk.agent?.messages?.[0]?.content) {
harness.traceStep('agent_output', chunk);
yield chunk.agent.messages[0].content;
}
}
}();
}
}
Skill 路由中心
根据用户问题自动匹配最优 Skill,实现意图识别与能力分发:
// packages/ai-core/src/skills/skill-router.ts
import { BaseSkill } from './base-skill';
export class SkillRouter {
private skills: Map<string, BaseSkill> = new Map();
register(skill: BaseSkill) {
this.skills.set(skill.id, skill);
}
async matchBestSkill(query: string, context: any): Promise<BaseSkill | null> {
const scores = await Promise.all(
Array.from(this.skills.values()).map(async skill => ({
skill,
score: await skill.matchIntent(query, context)
}))
);
const best = scores.sort((a, b) => b.score - a.score)0;
return best.score > 0.6 ? best.skill : null;
}
}
3.4 插件系统:可扩展的第三方能力机制
插件是 Skill 与 MCP 服务的打包载体,遵循统一规范,支持热加载与沙箱隔离,让第三方团队无需修改主项目代码即可扩展平台能力。
插件规范定义
每个插件为独立 npm 包,必须包含 devpilot.plugin.ts 入口文件,导出默认插件对象:
// 插件示例:code-review-plugin/src/devpilot.plugin.ts
import { definePlugin } from '@devpilot/plugins-sdk';
import { CodeReviewSkill } from './skills/code-review-skill';
export default definePlugin({
id: 'code-review-plugin',
name: '代码审查插件',
version: '1.0.0',
author: '架构组',
skills: new CodeReviewSkill(),
mcpServers: [
{
name: 'git-diff-server',
command: 'node',
args: './dist/mcp/git-diff-server.js'
}
]
});
插件加载器核心实现
// packages/backend/src/plugins/plugin-loader.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import { createRequire } from 'module';
import { SkillRouter } from '@devpilot/ai-core';
import { McpToolManager } from '@devpilot/ai-core';
@Injectable()
export class PluginLoaderService implements OnModuleInit {
private require = createRequire(__dirname);
private loadedPlugins = new Map();
constructor(
private skillRouter: SkillRouter,
private mcpManager: McpToolManager
) {}
async loadPlugin(pluginPath: string) {
// 清除模块缓存,支持热更新
delete this.require.cachethis.require.resolve(pluginPath);
const plugin = this.require(pluginPath).default;
// 注册 Skill
plugin.skills?.forEach(skill => this.skillRouter.register(skill));
// 注册 MCP 服务
plugin.mcpServers?.forEach(server => this.mcpManager.registerServer(server));
this.loadedPlugins.set(plugin.id, plugin);
return plugin;
}
async hotReload(pluginId: string) {
const plugin = this.loadedPlugins.get(pluginId);
if (plugin) {
// 先卸载旧能力,再重新加载
await this.unloadPlugin(pluginId);
await this.loadPlugin(plugin.path);
}
}
private async unloadPlugin(pluginId: string) {
// 省略 Skill 与 MCP 服务卸载逻辑
}
}
3.5 Agent Harness:可控可观测的 AI 运行时
Agent Harness 是生产级 AI 应用的核心保障,包裹在所有 Skill 执行外层,解决原生 Agent 执行不可控、不可观测、无评测的问题。
Harness 核心能力
-
生命周期管控:超时熔断、错误重试、优雅终止
-
安全管控:敏感工具拦截、高危操作二次确认、权限校验
-
全链路追踪:记录每一步工具调用、Token 消耗、耗时、输入输出
-
效果评测:自动对比预期结果与实际输出,统计 Skill 准确率
-
上下文管理:统一管理会话记忆、向量检索结果注入
Harness 核心实现
// packages/ai-core/src/harness/agent-harness.ts
import { v4 as uuidv4 } from 'uuid';
import { BaseSkill } from '.../skills/base-skill';
import { TraceService } from './trace.service';
import { SecurityGuard } from './security.guard';
import { EvaluationService } from './evaluation.service';
export class AgentHarness {
readonly taskId: string;
private startTime: number;
private timeoutMs = 120_000; // 默认 2 分钟超时
constructor(
private skill: BaseSkill,
private userId: string,
private traceService: TraceService,
private securityGuard: SecurityGuard,
private evaluationService: EvaluationService
) {
this.taskId = uuidv4();
this.startTime = Date.now();
}
async *execute(query: string, history: any\[\]): AsyncGenerator {
this.traceService.startTask(this.taskId, this.skill.id, this.userId);
// 1. 安全预检:校验用户权限与查询内容风险
const securityCheck = await this.securityGuard.checkQuery(query, this.userId);
if (!securityCheck.passed) {
yield `请求被拦截:${securityCheck.reason}`;
this.traceService.endTask(this.taskId, 'blocked');
return;
}
// 2. 超时控制器
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('TaskTimeout')), this.timeoutMs);
});
try {
const stream = this.skill.execute(query, history, this);
const taskPromise = (async () => {
for await (const chunk of stream) {
yield chunk;
}
})();
yield* Promise.race([taskPromise, timeoutPromise]) as any;
this.traceService.endTask(this.taskId, 'success');
// 3. 异步执行效果评测
this.evaluationService.evaluateTask(this.taskId, this.skill.id).catch();
} catch (error) {
const status = error.message === 'TaskTimeout' ? 'timeout' : 'failed';
this.traceService.endTask(this.taskId, status, error.message);
yield `执行异常:${error.message},任务ID:${this.taskId}`;
}
}
// 供 Skill 内部调用的工具获取与埋点方法
async getAvailableTools(scopes: string\[\]) {
return this.securityGuard.filterTools(scopes, this.userId);
}
traceStep(type: string, data: any) {
this.traceService.addStep(this.taskId, type, {
...data,
elapsed: Date.now() - this.startTime
});
}
}
3.6 前端交互:流式对话与可视化
前端采用 SSE 流式对接后端,实现打字机效果,并展示 Agent 执行链路。
SSE 流式请求封装
// packages/frontend/src/api/chat.ts
import { fetchEventSource } from '@microsoft/fetch-event-source';
export async function streamChat(
sessionId: string,
message: string,
onMessage: (chunk: string) => void,
onDone: () => void
) {
await fetchEventSource('/api/chat/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionId, message }),
onmessage(event) {
if (event.event === 'message') {
onMessage(event.data);
} else if (event.event === 'done') {
onDone();
}
}
});
}
后端 SSE 流式接口(NestJS)
// packages/backend/src/chat/chat.controller.ts
import { Controller, Post, Body, Res } from '@nestjs/common';
import { Response } from 'express';
import { ChatService } from './chat.service';
@Controller('api/chat')
export class ChatController {
constructor(private chatService: ChatService) {}
@Post('stream')
async streamChat(@Body() body: { sessionId: string; message: string }, @Res() res: Response) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const stream = await this.chatService.executeChat(body.sessionId, body.message);
for await (const chunk of stream) {
res.write(`event: message\ndata: ${JSON.stringify(chunk)}\n\n`);
}
res.write('event: done\ndata: ok\n\n');
res.end();
}
}
四、部署与运行
4.1 容器化部署
项目根目录提供 docker-compose.yml,一键启动所有依赖服务:
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: devpilot123
MYSQL_DATABASE: devpilot
ports:
- '3306:3306'
redis:
image: redis:7-alpine
ports:
- '6379:6379'
backend:
build: ./packages/backend
ports:
- '3000:3000'
depends_on:
-
mysql
-
redis
environment:
-
DATABASE_URL=mysql://root:devpilot123@mysql:3306/devpilot
-
REDIS_URL=redis://redis:6379
-
OPENAI_API_KEY=xxx
frontend:
build: ./packages/frontend
ports:
- '5173:80'
depends_on:
- backend
4.2 运行效果
-
对话主界面:支持多会话管理,流式输出回复,代码块高亮
-
技能市场:展示所有可用 Skill,支持手动选择触发
-
插件管理:插件列表、版本管理、一键热重载
-
执行链路:可视化展示 Agent 每一步工具调用、耗时、返回结果
-
评测面板:各 Skill 准确率统计、失败率排行、优化建议
五、扩展与优化方向
-
多模型支持:接入 DeepSeek、通义千问等国产大模型,支持模型路由与降级
-
RAG 知识库:接入企业 Wiki、接口文档,构建研发知识库,提升问答准确率
-
权限体系:对接企业 SSO,基于 RBAC 控制 Skill 与工具的访问权限
-
多端适配:开发飞书/企业微信机器人,让助手直接在办公软件中使用
-
私有化部署:对接本地大模型与向量数据库,满足数据安全合规要求
写在最后
本项目完整覆盖了当前企业级 AI 应用的核心架构要素:MCP 解决工具标准化问题,Skill 体系解决业务场景封装问题,插件机制解决生态扩展问题,Agent Harness 解决生产环境可控性问题。全栈 TypeScript 的技术栈,也让前端开发者可以极低的成本切入 AI 全栈开发。
整个项目并非 Demo 级玩具,而是可以直接作为企业内部 AI 助手的基础架构进行二次开发。你可以基于这套骨架,快速接入自己团队的内部系统,沉淀专属的研发 AI 能力。
需要我补充某一个模块的完整代码实现,或者细化某个技术点的原理讲解吗?