很多人第一次做 AI Agent,会把它理解成“更会聊天的机器人”。真正落地后才会发现,Agent 的重点不在聊天,而在把一个模糊目标拆成可执行步骤,调用工具获取信息,保存关键上下文,并在完成前做自检。本教程用“行业研究助理”作为案例:用户输入一个主题,Agent 自动搜索资料、整理来源、生成摘要、列出待确认问题,最后输出一份可复核的研究简报。
适用人群与准备工作
这篇教程适合三类人:第一,已经会调用大模型 API,想做出比普通聊天框更有用的应用;第二,产品或运营团队想把资料收集、竞品分析、周报整理自动化;第三,正在评估 Agent 平台的人,希望知道一个最小可行 Agent 应该包含哪些模块。如果你只是想让模型回答几个固定问题,普通 RAG 或提示词模板就够了,暂时不必上 Agent。
准备工作不复杂:一个可调用的大模型,一个后端服务,一到两个外部工具,例如搜索 API、网页读取器、数据库查询器或内部知识库接口。建议先用 Node.js 或 Python 做最小原型,不要一开始就接太多工具。工具越多,Agent 越容易在“能做很多事”里迷路。
第一步:把目标写成可检查的任务
Agent 最怕的输入是“帮我研究一下某公司”。这句话太宽,模型会自由发挥。更稳的写法是把目标拆成输出要求:研究对象是谁、时间范围是什么、必须包含哪些栏目、需要引用哪些来源、哪些信息不能猜。比如:
“请研究 2026 年上半年 AI 编程助手市场。输出 800 字简报,包含主要玩家、产品差异、商业模式、开发者关注点和三条待确认问题。只使用 2026 年之后的官方或权威媒体来源,不能把传闻写成事实。”
这个任务有明确边界,Agent 才知道什么时候应该继续查资料,什么时候应该停止。
第二步:设计工具调用层
一个研究助理 Agent 至少需要三类工具:搜索工具、网页读取工具和保存工具。搜索工具负责找到候选来源,网页读取工具负责提取正文与发布日期,保存工具负责把有效来源、摘要和中间判断写入数据库或临时状态。
工具接口要尽量窄。不要给模型一个万能的 run_code,而是提供像 searchWeb(query, dateRange)、readUrl(url)、saveSource(title, url, date, note) 这样的明确函数。每个工具返回结构化 JSON,而不是一大段松散文本。这样做的好处是之后更容易做校验,也能减少模型误读。
第三步:加入短期记忆与任务状态
Agent 的记忆不是“什么都记住”。在任务内,只需要保存四类信息:用户目标、已调用工具、已验证来源、未解决问题。可以用一个简单对象表示:
const state = {
goal: "研究 2026 年上半年 AI 编程助手市场",
sources: [],
findings: [],
openQuestions: [],
toolHistory: []
};每调用一次工具,就更新一次状态。每生成一个结论,就记录它来自哪个来源。这样最后输出时可以避免“凭印象写作”。如果你要做长期 Agent,再考虑用户偏好、历史项目、常用格式等长期记忆;最小版本不要过早复杂化。
第四步:让 Agent 先规划再执行
一个可靠的流程通常分为三段:计划、执行、复核。计划阶段让模型列出 3 到 6 个子任务,例如“搜索主要产品”“读取官方更新”“对比商业模式”“整理开发者痛点”。执行阶段逐个调用工具。复核阶段检查是否满足用户要求:字数是否够、来源是否可追溯、有没有把未确认内容写成事实。
不要让模型无限循环。建议设置最大工具调用次数,例如 8 次;如果 8 次后仍找不到证据,就把问题写进“待确认”,而不是继续消耗成本。对于生产环境,还要设置超时、费用上限和失败回退。
第五步:输出可复核结果
最终结果不要只给一段漂亮文字,应该包含来源、判断和不确定性。一个好的结构是:一句话结论、关键发现、来源列表、待确认问题、下一步建议。尤其在行业研究、竞品分析、法律合规、医疗金融等场景里,Agent 的价值不是“看起来很确定”,而是“能让人知道它为什么这么说”。
可复制的最小代码骨架
下面这个 Node.js 骨架能把 Agent 的关键部件跑起来:计划、工具调用、状态保存、最终汇总。真实项目可以把 searchWeb 接到 Tavily、SerpAPI、Bing Search 或内部搜索,把 readUrl 接到自己的网页解析服务。
const state = {
goal: "",
sources: [],
findings: [],
openQuestions: [],
};
async function searchWeb(query) {
const endpoint = process.env.SEARCH_API_ENDPOINT;
if (!endpoint) return [{ title: "OpenAI News", url: "https://openai.com/news/" }];
const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`);
return res.json();
}
async function readUrl(url) {
const res = await fetch(url);
const html = await res.text();
return {
url,
title: html.match(/<title>(.*?)<\/title>/i)?.[1] || url,
date: html.match(/datetime="([^"]+)"/i)?.[1] || "",
text: html.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<[^>]+>/g, " ").slice(0, 4000),
};
}
function saveFinding(source, note) {
state.sources.push(source);
state.findings.push({ note, sourceUrl: source.url });
}
async function runResearchAgent(goal) {
state.goal = goal;
const results = await searchWeb(`${goal} official source 2026`);
for (const item of results.slice(0, 3)) {
const source = await readUrl(item.url);
saveFinding(source, `从 ${source.title} 提取与目标相关的信息`);
}
return {
summary: state.findings.map((f) => f.note).join("\n"),
sources: state.sources.map((s) => ({ title: s.title, url: s.url })),
openQuestions: state.openQuestions,
};
}框架怎么选
如果你想快速做原型,用 LlamaIndex Workflows 或 LangGraph,它们适合把 Agent 拆成节点、状态和边。偏低代码可以用 Dify、n8n 或 Flowise,适合运营团队配置工具流。自己写框架只适合两种情况:业务权限很复杂,或你需要深度控制每一步日志、成本和失败回退。
界面验收图应该长什么样
教程截图不应该只截一个聊天框,至少要能证明系统真的跑了起来。第一张图截任务输入页,能看到用户目标、输出格式和来源约束。第二张图截工具调用日志,能看到 searchWeb、readUrl、saveFinding 的调用顺序、耗时和返回条数。第三张图截最终报告页,能看到每条结论后面绑定了来源 URL,以及“待确认问题”没有被写成事实。
如果你的界面暂时没有日志页,先在终端打印下面这种结构,再截图放进教程:
[tool] searchWeb query="AI coding assistants 2026 official source" duration=820ms results=5
[tool] readUrl url="https://..." duration=410ms date="2026-06-12"
[state] findings=3 sources=3 openQuestions=1
[guardrail] highRiskAction=false requiresHumanApproval=false常见坑
| 现象 | 直接原因 | 修法 | |------|----------|------| | Agent 一直在搜索,不输出结果 | 没有最大工具调用次数 | 设置 maxToolCalls = 8,超过后输出“待确认问题” | | 报告看起来完整,但找不到来源 | findings 没有绑定 sourceUrl | 每条结论必须保存 sourceUrl,渲染时无来源不展示 | | 模型乱选工具 | 工具名称太泛,例如 doTask | 改成 searchWeb、readUrl、saveFinding 这种动词明确的名字 | | 成本突然升高 | 循环里重复读取同一 URL | 对 URL 做缓存,同一任务内相同 URL 只读取一次 | | 误发邮件或误改数据 | 高风险工具直接执行 | 所有写操作先生成草稿,返回 draftId,用户确认后再执行 |
可以直接加一个保护函数:
function assertSafeAction(action) {
const highRisk = ["send_email", "delete_record", "deploy_prod", "change_config"];
if (highRisk.includes(action.type)) {
return { allowed: false, reason: "需要用户确认后执行" };
}
return { allowed: true };
}替代方案
如果你的任务只是基于固定文档问答,RAG 更简单、更稳定。如果你的任务是固定步骤自动化,例如每天拉取数据、生成报表、发送邮件,用传统脚本加一个总结模型就够了。如果你需要复杂审批、多人协作和权限管理,可以考虑 Dify、LangGraph、LlamaIndex Workflows、n8n、Make 等平台,而不是从零写框架。
小结
一个可用的 AI Agent,不是堆模型能力,而是把目标、工具、状态、校验和人类确认串起来。建议从一个低风险、高重复的任务开始:资料整理、会议纪要、竞品监控、客服草稿都很适合。先做一个只能完成小任务的 Agent,再逐步增加工具和权限。真正能上线的 Agent,往往不是最自由的,而是边界最清楚的。