跳到主要内容

AI Agent 原理与架构

问题

什么是 AI Agent?它与普通 LLM 对话有什么区别?Agent 有哪些核心架构模式、Skills 机制和 Memory 系统?主流 Agent 框架怎么选?

答案

AI Agent 是一个以 LLM 为「大脑」,能够自主感知环境、制定计划、调用工具、反思修正的智能系统。与普通 LLM 对话的区别在于:LLM 只是「一问一答」,而 Agent 能持续循环推理,自主完成多步任务

核心理解

Agent = LLM + 工具调用 + 记忆 + 规划。LLM 是大脑,工具是手脚,记忆是经验,规划是思维方式。四者缺一不可。

一、Agent 核心概念

Agent 与 LLM 的本质区别

维度普通 LLM 对话AI Agent
交互模式单轮/多轮问答自主循环执行
自主性被动响应用户输入主动分解任务、规划步骤
工具使用无或单次调用多工具组合、多步调用
记忆仅当前上下文窗口短期 + 长期记忆系统
错误处理无法自我修正观察结果、反思、重试
典型任务"翻译这段话""调研竞品并生成分析报告"

Agent 核心循环

所有 Agent 架构的本质都是一个感知 → 推理 → 行动 → 观察的循环:

lib/agent-core.ts
// Agent 核心抽象
interface Agent {
// 感知:接收用户输入和环境信息
perceive(input: string, context: AgentContext): PerceptionResult;
// 推理:分析当前状态,决定下一步行动
reason(perception: PerceptionResult, memory: Memory): Plan;
// 行动:执行具体操作(调用工具、生成文本等)
act(plan: Plan, tools: Tool[]): ActionResult;
// 观察:评估行动结果,决定是否继续
observe(result: ActionResult): ObservationResult;
}

interface AgentContext {
conversationHistory: Message[]; // 对话历史
availableTools: Tool[]; // 可用工具
memory: Memory; // 记忆系统
constraints: AgentConstraints; // 约束条件(超时、Token 预算等)
}

interface AgentConstraints {
maxIterations: number;
maxTokenBudget: number;
totalTimeout: number;
allowedTools: string[];
}

二、Agent 架构模式

1. ReAct(Reasoning + Acting)

最经典的 Agent 模式,LLM 交替进行推理和行动

patterns/react-agent.ts
// ReAct 模式的核心:LLM 在 system prompt 中被要求按 Thought/Action/Observation 格式输出
const REACT_SYSTEM_PROMPT = `你是一个能使用工具的 AI 助手。请按以下格式思考和行动:

Thought: 分析当前情况,思考下一步应该做什么
Action: 选择一个工具并调用
Observation: 观察工具返回的结果
... (重复 Thought/Action/Observation)
Thought: 我已经有足够的信息来回答了
Final Answer: 最终答案`;

// ReAct 的优势:推理过程透明、可解释性强
// ReAct 的劣势:每步都要推理,Token 消耗大;复杂任务可能迷失方向
async function reactLoop(
query: string,
tools: Tool[],
options: { maxSteps: number }
): Promise<string> {
const messages: Message[] = [
{ role: 'system', content: REACT_SYSTEM_PROMPT },
{ role: 'user', content: query },
];

for (let i = 0; i < options.maxSteps; i++) {
const response = await callLLM({ messages, tools });

// LLM 直接回答,结束循环
if (!response.toolCalls?.length) {
return response.content;
}

// 执行工具,将结果加入上下文,继续循环
messages.push({ role: 'assistant', content: response.content, toolCalls: response.toolCalls });

for (const toolCall of response.toolCalls) {
const result = await executeTool(toolCall, tools);
messages.push({ role: 'tool', toolCallId: toolCall.id, content: result });
}
}

return '达到最大步数限制';
}
ReAct 是面试高频考点

几乎所有 Agent 框架的底层都是 ReAct 模式的变体。理解了 ReAct,就理解了 Agent 的本质——让 LLM 在推理和行动之间交替,用工具结果辅助推理

2. Plan-and-Execute(计划与执行)

先制定完整计划,再逐步执行。适合目标明确、步骤可预见的任务:

patterns/plan-execute-agent.ts
interface Plan {
goal: string;
steps: PlanStep[];
}

interface PlanStep {
id: string;
description: string; // 步骤描述
tool?: string; // 需要调用的工具
dependencies: string[]; // 依赖的前置步骤
status: 'pending' | 'running' | 'done' | 'failed';
result?: string;
}

async function planAndExecute(query: string, tools: Tool[]): Promise<string> {
// 第一阶段:Planner 生成完整计划
const plan = await generatePlan(query, tools);
// 例如:"1. 搜索竞品信息 → 2. 提取关键数据 → 3. 对比分析 → 4. 生成报告"

// 第二阶段:按顺序执行每个步骤
for (const step of plan.steps) {
// 检查依赖是否完成
const depsReady = step.dependencies.every(
depId => plan.steps.find(s => s.id === depId)?.status === 'done'
);
if (!depsReady) continue;

step.status = 'running';

if (step.tool) {
step.result = await executeTool(step, tools);
} else {
// 纯推理步骤,用 LLM 处理
step.result = await llmReason(step, plan);
}

step.status = 'done';

// 关键:每步执行完后评估是否需要修改后续计划
const needReplan = await evaluateProgress(plan, step);
if (needReplan) {
const revisedPlan = await replan(plan, step);
plan.steps = revisedPlan.steps;
}
}

return await summarizeResults(plan);
}
Plan-and-Execute vs ReAct 的选择
  • ReAct:适合探索性任务("帮我调研这个话题"),不确定需要几步
  • Plan-and-Execute:适合结构化任务("生成一份包含 A/B/C 的报告"),步骤可预见
  • 实际应用中,很多框架混合使用:先 Plan 制定大纲,每个步骤内部用 ReAct 执行

3. Multi-Agent(多智能体协作)

多个 Agent 分工协作,各自负责不同子任务:

patterns/multi-agent.ts
interface AgentRole {
name: string;
systemPrompt: string; // 定义角色的专业能力和行为规范
tools: Tool[]; // 该角色可用的工具
model?: string; // 可以为不同角色使用不同模型(成本优化)
}

// 多 Agent 的核心:每个 Agent 有独立的角色定义和工具集
const agents: AgentRole[] = [
{
name: 'researcher',
systemPrompt: '你是一个专业的调研助手,擅长搜索和整理信息...',
tools: [webSearchTool, urlFetchTool],
model: 'claude-sonnet-4-6', // 调研用性价比高的模型
},
{
name: 'analyst',
systemPrompt: '你是一个数据分析师,擅长分析数据和生成洞察...',
tools: [dbQueryTool, chartTool],
model: 'claude-opus-4-6', // 分析用最强模型
},
{
name: 'writer',
systemPrompt: '你是一个技术写作专家,擅长将复杂内容写成清晰的文档...',
tools: [markdownTool],
model: 'claude-sonnet-4-6',
},
];

// 编排器:协调多个 Agent 完成任务
async function orchestrate(
task: string,
agents: AgentRole[]
): Promise<string> {
// 1. 编排器分解任务,分配给不同 Agent
const assignments = await planAssignments(task, agents);

// 2. 按依赖关系执行(可并行的步骤并行执行)
const results = new Map<string, string>();

for (const batch of assignments.batches) {
// 同一批次内的任务并行执行
const batchResults = await Promise.all(
batch.map(async (assignment) => {
const agent = agents.find(a => a.name === assignment.agentName)!;
// 将前序 Agent 的结果作为上下文传入
const context = assignment.dependencies
.map(dep => results.get(dep))
.filter(Boolean)
.join('\n');

return runAgent(agent, assignment.task, context);
})
);

batchResults.forEach((result, i) => {
results.set(batch[i].id, result);
});
}

// 3. 汇总所有结果
return await synthesize(task, results);
}

三种 Agent 模式对比:

维度ReActPlan-and-ExecuteMulti-Agent
自主性逐步推理先规划后执行分工协作
适用场景探索性任务结构化任务复杂大型任务
可控性中等较高(计划可审核)高(各角色独立)
Token 效率低(每步推理)中等高(各角色只关注子任务)
实现复杂度中等
代表框架LangChain ReActLangGraphCrewAI、AutoGen

三、Agent Skills(技能系统)

Skills 是 Agent 能力的模块化封装——比单个 Tool 更高层的抽象,一个 Skill 可能编排多个 Tool 完成一个完整子任务。

Skill 与 Tool 的区别

维度Tool(工具)Skill(技能)
粒度单一操作(查天气、查数据库)完整子任务("调研一个话题")
编排无,被动调用内部可编排多个 Tool
上下文无状态,每次独立调用有状态,可维护中间结果
错误处理返回错误给 LLM 判断内部重试和降级逻辑
示例web_search(query)research(topic) = 搜索 + 筛选 + 摘要
lib/skill.ts
// Skill 接口定义
interface Skill {
name: string;
description: string; // 给 LLM 看的描述,决定何时调用
inputSchema: z.ZodType; // 输入参数 schema
outputSchema: z.ZodType; // 输出格式 schema

// Skill 的核心:内部编排多个 Tool 完成子任务
execute(input: unknown, context: SkillContext): Promise<SkillResult>;
}

interface SkillContext {
tools: Tool[]; // 可用的底层工具
memory: Memory; // 记忆系统
llm: LLMClient; // 可以调用 LLM 做推理
parentAgent: Agent; // 父 Agent 引用
}

interface SkillResult {
success: boolean;
data: unknown;
summary: string; // 给 LLM 的摘要(控制传回的信息量)
artifacts?: Artifact[]; // 生成的文件、图表等
}

Skill 实现示例

skills/research-skill.ts
import { z } from 'zod';

// "调研" Skill:编排搜索、抓取、摘要三个步骤
const researchSkill: Skill = {
name: 'research',
description: '深入调研一个话题。搜索多个来源,提取关键信息,生成结构化摘要。当需要全面了解某个话题时调用。',
inputSchema: z.object({
topic: z.string().describe('调研话题'),
depth: z.enum(['quick', 'thorough']).default('quick').describe('调研深度'),
maxSources: z.number().default(5).describe('最大来源数'),
}),
outputSchema: z.object({
summary: z.string(),
keyFindings: z.array(z.string()),
sources: z.array(z.object({ title: z.string(), url: z.string() })),
}),

async execute(input, context) {
const { topic, depth, maxSources } = this.inputSchema.parse(input);

// 步骤 1:搜索多个来源
const searchResults = await context.tools
.find(t => t.name === 'web_search')!
.execute({ query: topic, type: 'web' });

const urls = JSON.parse(searchResults).slice(0, maxSources);

// 步骤 2:并行抓取每个来源的内容
const contents = await Promise.allSettled(
urls.map((url: { link: string }) =>
context.tools.find(t => t.name === 'url_fetch')!.execute({ url: url.link })
)
);

const successfulContents = contents
.filter((c): c is PromiseFulfilledResult<string> => c.status === 'fulfilled')
.map(c => c.value);

// 步骤 3:用 LLM 汇总分析(Skill 内部可以调用 LLM)
const analysis = await context.llm.chat({
messages: [{
role: 'user',
content: `请分析以下关于"${topic}"的资料,提取关键信息:\n\n${successfulContents.join('\n---\n')}`,
}],
});

return {
success: true,
data: { summary: analysis.content, sources: urls },
summary: `已完成「${topic}」调研,找到 ${urls.length} 个来源。`,
};
},
};

Skill Discovery(技能发现)

Agent 可以动态发现和加载新技能,而不是编译时固定:

lib/skill-registry.ts
// 技能注册中心
class SkillRegistry {
private skills = new Map<string, Skill>();
private mcpServers: MCPServer[] = [];

// 注册本地 Skill
register(skill: Skill): void {
this.skills.set(skill.name, skill);
}

// 通过 MCP 协议动态发现远程 Skill
async discoverFromMCP(serverUrl: string): Promise<void> {
const server = await connectMCP(serverUrl);
const remoteTools = await server.listTools();

// 将 MCP Tool 适配为 Skill
for (const tool of remoteTools) {
this.register({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
outputSchema: z.unknown(),
execute: async (input) => {
const result = await server.callTool(tool.name, input);
return { success: true, data: result, summary: String(result) };
},
});
}
}

// 获取所有可用 Skill 的描述(传给 LLM)
getSkillDescriptions(): ToolDefinition[] {
return Array.from(this.skills.values()).map(s => ({
name: s.name,
description: s.description,
parameters: zodToJsonSchema(s.inputSchema),
}));
}

// 执行指定 Skill
async execute(name: string, input: unknown, context: SkillContext): Promise<SkillResult> {
const skill = this.skills.get(name);
if (!skill) throw new Error(`Skill "${name}" not found`);
return skill.execute(input, context);
}
}
Skill 与 MCP 的关系

MCP(Model Context Protocol) 是标准化的工具发现和调用协议。Skill 可以通过 MCP 动态发现——Agent 连接到 MCP Server 后,自动获得该 Server 提供的所有能力。这使得 Agent 的能力可以即插即用地扩展。

四、Memory 系统(记忆)

LLM 的上下文窗口有限(4K~200K tokens),Agent 需要额外的记忆系统来存储和检索历史信息。

记忆类型

记忆类型存储位置生命周期典型内容
短期记忆对话上下文当前会话对话历史、用户当前意图
工作记忆变量/缓存当前任务推理中间结果、工具返回值
长期记忆向量数据库/文件跨会话持久化用户偏好、历史交互摘要
lib/memory.ts
interface Memory {
// 短期记忆:管理当前对话上下文
shortTerm: ShortTermMemory;
// 长期记忆:跨会话持久化
longTerm: LongTermMemory;
// 工作记忆:当前任务的中间状态
working: WorkingMemory;
}

// 短期记忆:上下文窗口管理
class ShortTermMemory {
private messages: Message[] = [];
private maxTokens: number;

constructor(maxTokens: number = 8000) {
this.maxTokens = maxTokens;
}

add(message: Message): void {
this.messages.push(message);
// 超过 Token 限制时,压缩早期消息
this.compress();
}

// 压缩策略:用 LLM 对早期对话生成摘要
private async compress(): Promise<void> {
const totalTokens = estimateTokens(this.messages);
if (totalTokens <= this.maxTokens) return;

// 保留最近 N 条消息,将更早的消息压缩为摘要
const keepRecent = 10;
const oldMessages = this.messages.slice(0, -keepRecent);
const recentMessages = this.messages.slice(-keepRecent);

const summary = await llm.chat({
messages: [{
role: 'user',
content: `请将以下对话历史压缩为简洁的摘要,保留关键信息:\n${formatMessages(oldMessages)}`,
}],
});

this.messages = [
{ role: 'system', content: `[历史对话摘要] ${summary.content}` },
...recentMessages,
];
}
}

// 长期记忆:基于向量检索
class LongTermMemory {
private vectorStore: VectorStore;

constructor(vectorStore: VectorStore) {
this.vectorStore = vectorStore;
}

// 存储记忆(自动生成 Embedding)
async store(content: string, metadata: Record<string, unknown>): Promise<void> {
const embedding = await generateEmbedding(content);
await this.vectorStore.insert({
content,
embedding,
metadata: { ...metadata, timestamp: Date.now() },
});
}

// 检索相关记忆
async recall(query: string, topK: number = 5): Promise<MemoryItem[]> {
const queryEmbedding = await generateEmbedding(query);
return this.vectorStore.search(queryEmbedding, topK);
}

// 重要:定期清理和合并相似记忆
async consolidate(): Promise<void> {
const allMemories = await this.vectorStore.getAll();
const clusters = clusterBySimilarity(allMemories, 0.9);

for (const cluster of clusters) {
if (cluster.length > 1) {
// 合并相似记忆为一条
const merged = await llm.chat({
messages: [{
role: 'user',
content: `合并以下相似记忆为一条:\n${cluster.map(m => m.content).join('\n')}`,
}],
});
await this.vectorStore.replace(cluster.map(m => m.id), merged.content);
}
}
}
}

// 工作记忆:当前任务的 Scratchpad
class WorkingMemory {
private data = new Map<string, unknown>();

set(key: string, value: unknown): void { this.data.set(key, value); }
get<T>(key: string): T | undefined { return this.data.get(key) as T; }
clear(): void { this.data.clear(); }

// 将工作记忆序列化为 LLM 可读的上下文
toContext(): string {
const entries = Array.from(this.data.entries());
if (entries.length === 0) return '';
return '当前任务上下文:\n' + entries
.map(([k, v]) => `- ${k}: ${JSON.stringify(v)}`)
.join('\n');
}
}

五、Agent 框架生态

主流框架对比

框架语言核心特点适用场景
LangChainJS/Python链式编排、生态最丰富快速原型、通用 Agent
LangGraphJS/Python图状态机、精确控制流复杂多步 Agent
Vercel AI SDKJS/TS流式 UI、React 集成好前端 AI 应用
CrewAIPython角色扮演、多 Agent 协作多角色协作任务
AutoGenPython多 Agent 对话研究、代码生成
Claude Agent SDKJS/Python原生 Claude 支持、简洁Claude 生态 Agent
MastraJS/TSTypeScript 优先、Agent 工作流TS 全栈 Agent

LangGraph 示例

LangGraph 将 Agent 建模为状态图,每个节点是一个处理步骤,边定义流转条件:

frameworks/langgraph-example.ts
import { StateGraph, Annotation } from '@langchain/langgraph';
import { ChatAnthropic } from '@langchain/anthropic';

// 1. 定义状态
const AgentState = Annotation.Root({
messages: Annotation<Message[]>({ reducer: (a, b) => [...a, ...b] }),
plan: Annotation<string[]>({ reducer: (_, b) => b }),
currentStep: Annotation<number>({ reducer: (_, b) => b }),
});

// 2. 定义节点(处理函数)
async function planner(state: typeof AgentState.State) {
const llm = new ChatAnthropic({ model: 'claude-sonnet-4-6' });
const plan = await llm.invoke([
{ role: 'system', content: '你是任务规划专家,请将任务分解为步骤' },
...state.messages,
]);
return { plan: parsePlan(plan.content), currentStep: 0 };
}

async function executor(state: typeof AgentState.State) {
const step = state.plan[state.currentStep];
const result = await executeStep(step);
return {
messages: [{ role: 'assistant', content: result }],
currentStep: state.currentStep + 1,
};
}

// 条件判断:是否还有下一步
function shouldContinue(state: typeof AgentState.State): string {
return state.currentStep < state.plan.length ? 'executor' : 'end';
}

// 3. 构建状态图
const graph = new StateGraph(AgentState)
.addNode('planner', planner)
.addNode('executor', executor)
.addEdge('__start__', 'planner')
.addConditionalEdges('planner', shouldContinue)
.addConditionalEdges('executor', shouldContinue)
.compile();

// 4. 执行
const result = await graph.invoke({
messages: [{ role: 'user', content: '分析最近一周的销售数据趋势' }],
});

Vercel AI SDK 示例

前端友好,内置流式 UI 渲染:

frameworks/vercel-ai-example.ts
import { generateText, tool } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { z } from 'zod';

const result = await generateText({
model: anthropic('claude-sonnet-4-6'),
// Vercel AI SDK 的 tool 定义非常简洁
tools: {
weather: tool({
description: '获取天气信息',
parameters: z.object({ city: z.string() }),
execute: async ({ city }) => {
const data = await fetch(`/api/weather?city=${city}`);
return data.json();
},
}),
search: tool({
description: '搜索互联网',
parameters: z.object({ query: z.string() }),
execute: async ({ query }) => {
const data = await fetch(`/api/search?q=${query}`);
return data.json();
},
}),
},
maxSteps: 10, // Agent 最大循环次数
prompt: '上海今天适合户外运动吗?',
});

Claude Agent SDK 示例

frameworks/claude-agent-example.ts
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic();

// Claude Agent SDK 使用原生的 tool_use 循环
async function claudeAgent(userMessage: string): Promise<string> {
const tools: Anthropic.Tool[] = [
{
name: 'read_file',
description: '读取文件内容',
input_schema: {
type: 'object',
properties: {
path: { type: 'string', description: '文件路径' },
},
required: ['path'],
},
},
{
name: 'write_file',
description: '写入文件内容',
input_schema: {
type: 'object',
properties: {
path: { type: 'string', description: '文件路径' },
content: { type: 'string', description: '文件内容' },
},
required: ['path', 'content'],
},
},
];

const messages: Anthropic.MessageParam[] = [
{ role: 'user', content: userMessage },
];

// Agentic Loop:持续循环直到 stop_reason 不是 tool_use
while (true) {
const response = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 4096,
tools,
messages,
});

// 不需要工具调用,返回最终结果
if (response.stop_reason === 'end_turn') {
const textBlock = response.content.find(b => b.type === 'text');
return textBlock?.text ?? '';
}

// 需要工具调用
messages.push({ role: 'assistant', content: response.content });

const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const block of response.content) {
if (block.type === 'tool_use') {
const result = await executeLocalTool(block.name, block.input);
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
content: result,
});
}
}

messages.push({ role: 'user', content: toolResults });
}
}

六、Agent 评估与可观测性

Agent 的行为比普通 LLM 更复杂,需要专门的评估和监控手段。

评估维度

维度指标说明
任务完成率Success Rate能否正确完成给定任务
步骤效率Avg Steps / Task完成任务平均需要几步
工具使用准确率Tool Selection Accuracy是否选了正确的工具、参数是否正确
成本效率Token / Task每个任务消耗的 Token 数
延迟Time to Complete从用户输入到最终回答的时间
安全性Safety Violations是否触发了不安全的操作

可观测性

lib/agent-observability.ts
// Agent 追踪:记录每一步的详细信息
interface AgentTrace {
traceId: string;
startTime: number;
endTime?: number;
spans: AgentSpan[];
totalTokens: number;
totalCost: number;
}

interface AgentSpan {
spanId: string;
parentId?: string;
type: 'llm_call' | 'tool_call' | 'skill_call' | 'planning';
name: string;
input: unknown;
output: unknown;
duration: number;
tokens?: { input: number; output: number };
status: 'success' | 'error';
error?: string;
}

// 追踪中间件:包装 Agent 的每个操作
function withTracing<T>(
trace: AgentTrace,
spanType: AgentSpan['type'],
name: string,
fn: () => Promise<T>
): Promise<T> {
const span: AgentSpan = {
spanId: generateId(),
type: spanType,
name,
input: null,
output: null,
duration: 0,
status: 'success',
};

const start = Date.now();

return fn()
.then(result => {
span.output = result;
span.duration = Date.now() - start;
trace.spans.push(span);
return result;
})
.catch(error => {
span.status = 'error';
span.error = error.message;
span.duration = Date.now() - start;
trace.spans.push(span);
throw error;
});
}
可观测性工具推荐
  • LangSmith:LangChain 官方追踪平台,可视化 Agent 执行链路
  • Langfuse:开源替代方案,支持自部署
  • Braintrust:Agent 评估 + 追踪一体化

七、Agent 设计最佳实践

构建可靠 Agent 的关键原则
  1. 从简单开始:先用 ReAct 模式验证可行性,再逐步增加复杂度
  2. 工具设计决定 Agent 能力上限:好的工具描述和参数设计比复杂的 Prompt 更重要
  3. 总是设置安全边界:maxIterations、timeout、Token 预算缺一不可
  4. 观察和反思是关键:让 Agent 评估每步结果,及时调整策略
  5. 人机协作优于全自动:关键决策让用户确认,而非完全自主
  6. 记忆管理要有策略:不是所有信息都值得记住,需要压缩和遗忘机制

常见面试问题

Q1: 什么是 AI Agent?和普通 LLM 对话有什么区别?

答案

AI Agent 是以 LLM 为核心,具备自主感知、规划、工具使用和记忆能力的智能系统。

与普通 LLM 对话的 3 个核心区别:

  1. 自主循环:Agent 可以多轮推理,自主决定下一步做什么,直到任务完成;普通对话是一问一答
  2. 工具使用:Agent 能调用外部工具(搜索、数据库、API)获取信息和执行操作;普通对话只能基于已有知识回答
  3. 记忆系统:Agent 有短期/长期记忆,能跨会话记住用户偏好和历史;普通对话仅限当前上下文窗口

一句话:LLM 是大脑,Agent 是完整的智能体——有大脑、有手脚(工具)、有记忆。

Q2: 解释 ReAct 模式的原理和执行流程

答案

ReAct = Reasoning + Acting,核心思想是让 LLM 交替进行推理和行动

  1. Thought(推理):LLM 分析当前情况,思考应该做什么
  2. Action(行动):调用一个工具执行操作
  3. Observation(观察):获取工具返回结果
  4. 重复 1-3,直到 LLM 认为可以给出最终答案

ReAct 的关键优势是可解释性——每一步都有 Thought 说明推理过程,方便调试和审查。劣势是每步都需要 LLM 推理,Token 消耗较大。

Q3: Plan-and-Execute 和 ReAct 模式有什么区别?如何选择?

答案

维度ReActPlan-and-Execute
思维方式边想边做(逐步推理)先想后做(先规划再执行)
适用任务探索性(不确定需要几步)结构化(步骤可预见)
灵活性高(每步可调整方向)中等(计划变更成本高)
效率低(每步都推理)高(规划一次,执行多步)

选择建议:

  • 任务简单、步骤少 → ReAct
  • 任务复杂、步骤多且可预见 → Plan-and-Execute
  • 实际项目常用混合模式:Plan-and-Execute 制定大纲,每个步骤内部用 ReAct 灵活执行

Q4: Multi-Agent 系统的优劣势是什么?

答案

优势:

  • 专业分工:每个 Agent 只关注子任务,Prompt 更精准,工具集更小
  • 并行执行:无依赖的子任务可以并行,提高效率
  • 成本优化:不同角色用不同模型(简单任务用小模型,复杂分析用大模型)
  • 可扩展:新增能力只需添加新 Agent,不影响现有逻辑

劣势:

  • 编排复杂:需要 Orchestrator 协调,上下文传递、错误处理复杂
  • 通信开销:Agent 间信息传递消耗额外 Token
  • 调试困难:多 Agent 交互的链路追踪和问题定位更复杂
  • 过度设计风险:简单任务不需要多 Agent,反而增加复杂度

Q5: Agent 的 Skill 和 Tool 有什么区别?

答案

Tool 是原子操作(查天气、读文件),Skill 是复合能力(调研一个话题 = 搜索 + 抓取 + 摘要)。

核心区别:

  1. 粒度:Tool 是单一函数调用,Skill 内部编排多个 Tool
  2. 状态:Tool 无状态,Skill 可维护中间结果
  3. 智能:Tool 只执行,Skill 内部可以调用 LLM 做判断和推理
  4. 错误处理:Tool 返回错误给 Agent 判断,Skill 内部可以重试和降级

实际框架中,Skill 通常实现为一个高层 Tool——对 LLM 来说调用方式相同,但内部逻辑更复杂。

Q6: Agent 的 Memory 系统有哪些类型?各有什么用?

答案

三种记忆类型:

  1. 短期记忆(Short-term):当前对话的上下文历史。受上下文窗口限制,需要压缩策略(摘要早期对话)
  2. 工作记忆(Working):当前任务的中间状态,如工具返回值、推理暂存结果。任务结束后清空
  3. 长期记忆(Long-term):跨会话持久化,通常用向量数据库存储。通过语义相似度检索相关记忆

长期记忆的实现方式:

  • 向量检索:将记忆 Embedding 后存入向量数据库,查询时用语义相似度检索
  • 知识图谱:结构化存储实体和关系,适合事实性知识
  • 文件系统:直接写入文件,适合简单场景(如 Claude Code 的 memory 系统)

Q7: 如何评估一个 Agent 的质量?

答案

5 个核心评估维度:

  1. 任务完成率:给定一组测试任务,Agent 能正确完成多少比例
  2. 步骤效率:完成任务平均需要多少步。步骤越少说明推理越高效
  3. 工具使用准确率:是否选了正确的工具,参数是否正确
  4. 成本:每个任务消耗的 Token 数和 API 调用费用
  5. 安全性:是否触发了不安全操作,是否泄露了敏感信息

评估方法:

  • 构建 Benchmark 数据集(输入 + 期望输出)
  • LLM-as-Judge(让另一个 LLM 评估结果质量)
  • 追踪 端到端指标(延迟、成功率、用户满意度)

Q8: Agent 如何处理工具调用失败的情况?

答案

3 层错误处理策略:

  1. Tool 层重试:工具内部对暂时性错误(网络超时、限流)自动重试,使用指数退避
  2. Agent 层反思:工具返回错误后,LLM 分析错误原因,决定重试(换参数)、换工具、或告知用户
  3. Skill 层降级:Skill 内部实现降级逻辑(如主 API 失败,切换到备用 API)
// 工具结果中包含错误信息,让 LLM 决策
const toolResult = {
error: 'Rate limit exceeded, retry after 5s',
suggestion: '可以换一个搜索引擎或稍后重试',
};
// LLM 看到错误后会自主选择:重试、换工具或直接回答

关键原则:永远不要隐藏错误,将错误信息传回 LLM,让它做决策。

Q9: 主流 Agent 框架如何选型?

答案

根据场景选择:

  • 前端 AI 应用Vercel AI SDK:流式 UI、React hooks、TypeScript 优先
  • 快速原型LangChain:生态丰富、集成多、上手快
  • 复杂工作流LangGraph:精确控制流、状态管理、可视化调试
  • 多 Agent 协作CrewAI / AutoGen:角色定义、任务分配
  • Claude 生态Claude Agent SDK:原生支持、API 简洁
  • TypeScript 全栈Mastra:TS 优先、Agent 工作流

选型关键考虑:语言生态(JS vs Python)、控制粒度需求、是否需要流式 UI、团队熟悉度。

Q10: Agent 的安全风险有哪些?如何防范?

答案

5 大安全风险:

  1. Prompt 注入:恶意输入诱导 Agent 执行危险操作

    • 防范:工具白名单、参数校验、敏感操作二次确认
  2. 过度授权:Agent 拥有超出需要的权限

    • 防范:最小权限原则、每个角色独立工具集
  3. 无限循环:Agent 陷入死循环消耗资源

    • 防范:maxIterations、totalTimeout、Token 预算
  4. 数据泄露:工具结果中的敏感信息被 LLM 记忆或泄露

    • 防范:结果脱敏、敏感字段过滤
  5. 级联故障:一个工具失败导致 Agent 行为不可预测

    • 防范:错误隔离、降级策略、人工确认关键操作

核心原则:Human-in-the-Loop——关键决策让用户确认,不要完全信任 Agent 的自主判断。

Q11: 如何优化 Agent 的 Token 消耗?

答案

Agent 的 Token 消耗远高于普通对话(每次循环都带上全部历史),优化策略:

  1. 精简工具描述:只传入当前可能用到的工具,而非全部工具
  2. 压缩工具结果:截断过长结果,只返回关键字段
  3. 上下文窗口管理:早期对话压缩为摘要
  4. 分层模型:简单任务用小模型(路由/分类),复杂任务用大模型(分析/生成)
  5. 缓存:相同工具调用(相同参数)缓存结果,避免重复执行
  6. Skill 封装:Skill 内部处理细节,只向 Agent 返回摘要

Q12: Skill Discovery 和 MCP 协议有什么关系?

答案

MCP(Model Context Protocol)是标准化的工具发现和调用协议,它让 Agent 的 Skill Discovery 成为可能:

  1. Agent 连接到 MCP Server
  2. 调用 listTools() 获取 Server 提供的所有工具描述
  3. 将这些工具动态注册为 Agent 的 Skill
  4. Agent 调用工具时,通过 MCP 协议转发给对应 Server 执行

这样 Agent 的能力可以即插即用——连接不同的 MCP Server 就获得不同的能力(数据库操作、文件系统、第三方 API 等),无需修改 Agent 代码。

Q13: Agent 的工作记忆(Working Memory)和 RAG 有什么区别?

答案

维度工作记忆RAG
作用存储当前任务的中间结果检索外部知识库
生命周期当前任务内,任务结束清空持久存储,跨任务可用
数据来源Agent 推理产生的中间值预先构建的文档/知识库
检索方式Key-Value 直接访问向量语义相似度搜索
典型内容工具返回值、中间计算结果文档、FAQ、历史案例

两者互补:RAG 提供外部知识,工作记忆存储任务进展。Agent 在推理时同时查询两者。

Q14: 如何让 Agent 支持「用户确认」机制?

答案

对于敏感操作(删除数据、发送邮件、支付),Agent 应暂停等待用户确认:

  1. 维护一个 requireConfirmation 工具列表
  2. Agent 要调用这些工具时,不立即执行,而是向前端发送确认请求
  3. 前端展示确认对话框(工具名、参数、预期效果)
  4. 用户确认 → 继续执行;用户拒绝 → 将「用户拒绝了此操作」作为工具结果返回给 LLM
  5. LLM 收到拒绝后,会自主调整策略(换方案或询问用户意图)

这就是 Human-in-the-Loop 模式,在自动化和安全性之间取得平衡。

Q15: Agent 技术的未来趋势是什么?

答案

5 个关键趋势:

  1. Computer Use / GUI Agent:Agent 直接操作图形界面(点击、输入、截图识别),而非仅调用 API
  2. Multi-Modal Agent:结合视觉、语音、代码等多模态能力,处理更复杂的任务
  3. Agent-to-Agent 协作:标准化的 Agent 间通信协议(如 A2A),不同 Agent 协作完成任务
  4. 长期自主 Agent:能持续运行数小时/天,自主完成大型项目(如 Devin、Claude Code)
  5. Skill 市场化:MCP 生态成熟后,Agent 能从「技能市场」动态获取新能力

相关链接