用 Claude Code 开发聊天机器人的实战指南
用 Claude Code 高效开发 AI 聊天机器人,涵盖会话历史管理、流式响应、RAG 构成,配合可运行代码讲解。
用 Claude Code 开发聊天机器人
开发 AI 聊天机器人涉及 UI 实现、API 联动、会话管理、流式处理等许多环节。借助 Claude Code,你可以把这些环节整合在一起,在短时间内构建出一个完整的聊天机器人。
实现基础的聊天 UI
> 用 React 帮我写一个聊天机器人组件。
> 要支持流式响应、显示会话历史,并带有输入表单。
import { useState, useRef, useEffect } from "react";
interface Message {
id: string;
role: "user" | "assistant";
content: string;
}
export function ChatBot() {
const [messages, setMessages] = useState<Message[]>([]);
const [input, setInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
const sendMessage = async () => {
if (!input.trim() || isLoading) return;
const userMessage: Message = {
id: crypto.randomUUID(),
role: "user",
content: input,
};
setMessages((prev) => [...prev, userMessage]);
setInput("");
setIsLoading(true);
const assistantId = crypto.randomUUID();
setMessages((prev) => [
...prev,
{ id: assistantId, role: "assistant", content: "" },
]);
try {
const response = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
messages: [...messages, userMessage].map(({ role, content }) => ({
role,
content,
})),
}),
});
const reader = response.body!.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
setMessages((prev) =>
prev.map((m) =>
m.id === assistantId
? { ...m, content: m.content + chunk }
: m
)
);
}
} catch (error) {
setMessages((prev) =>
prev.map((m) =>
m.id === assistantId
? { ...m, content: "An error occurred. Please try again." }
: m
)
);
}
setIsLoading(false);
};
return (
<div className="flex flex-col h-[600px] border rounded-lg">
<div className="flex-1 overflow-y-auto p-4 space-y-4">
{messages.map((msg) => (
<div
key={msg.id}
className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"}`}
>
<div
className={`max-w-[70%] p-3 rounded-lg ${
msg.role === "user"
? "bg-blue-600 text-white"
: "bg-gray-100 text-gray-900"
}`}
>
{msg.content}
</div>
</div>
))}
<div ref={messagesEndRef} />
</div>
<div className="border-t p-4 flex gap-2">
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && !e.shiftKey && sendMessage()}
placeholder="Type a message..."
className="flex-1 p-2 border rounded-lg"
disabled={isLoading}
/>
<button
onClick={sendMessage}
disabled={isLoading}
className="px-4 py-2 bg-blue-600 text-white rounded-lg disabled:opacity-50"
>
送信
</button>
</div>
</div>
);
}
支持流式响应的 API 路由
下面是一个在后端调用 Anthropic API、并以流式方式返回结果的 API 路由。
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
export async function POST(request: Request) {
const { messages } = await request.json();
const stream = await client.messages.stream({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: "あなたは親切で丁寧なアシスタントです。日本語で回答してください。",
messages,
});
const encoder = new TextEncoder();
const readable = new ReadableStream({
async start(controller) {
for await (const event of stream) {
if (
event.type === "content_block_delta" &&
event.delta.type === "text_delta"
) {
controller.enqueue(encoder.encode(event.delta.text));
}
}
controller.close();
},
});
return new Response(readable, {
headers: { "Content-Type": "text/plain; charset=utf-8" },
});
}
会话历史的持久化
把会话保存到数据库,让用户之后可以接着之前的对话继续聊。
import { db } from "@/lib/database";
export async function saveConversation(
userId: string,
messages: Message[]
) {
return db.conversation.upsert({
where: { id: `${userId}-current` },
update: {
messages: JSON.stringify(messages),
updatedAt: new Date(),
},
create: {
id: `${userId}-current`,
userId,
messages: JSON.stringify(messages),
},
});
}
export async function loadConversation(userId: string): Promise<Message[]> {
const conv = await db.conversation.findUnique({
where: { id: `${userId}-current` },
});
return conv ? JSON.parse(conv.messages as string) : [];
}
集成 RAG(检索增强生成)
如果要做一个基于公司内部文档来回答问题的聊天机器人,RAG 结构会非常有用。
import { searchDocuments } from "@/lib/vector-search";
async function generateRAGResponse(query: string, conversationHistory: Message[]) {
// Search related documents
const relevantDocs = await searchDocuments(query, { limit: 5 });
const context = relevantDocs
.map((doc) => `---\n${doc.title}\n${doc.content}\n---`)
.join("\n");
const systemPrompt = `以下のドキュメントを参考に質問に回答してください。
ドキュメントに情報がない場合は「その情報は見つかりませんでした」と答えてください。
${context}`;
return client.messages.stream({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
system: systemPrompt,
messages: conversationHistory,
});
}
关于如何通过与 MCP 服务器联动来扩展功能,可以参阅MCP 服务器指南;关于如何设计高效的提示词,可以参阅改进提示词的 5 个技巧。
总结
借助 Claude Code,你可以高效地开发出涵盖聊天 UI、流式 API、会话管理乃至 RAG 结构的完整聊天机器人。采用循序渐进、逐步添加功能的做法会更有效果。
更多细节请参阅 Claude Code 官方文档和 Anthropic API 参考。
2026 生产化升级
聊天机器人不是一个漂亮的输入框,而是一个能接收用户问题、保留必要上下文、再给出下一步回复的小型应用。用更简单的话说,它是网站里的对话入口,可以承担客服、售前咨询、内部知识库检索、课程推荐或故障信息收集。真正决定效果的不是模型有多强,而是你有没有定义清楚它能回答什么、不能回答什么、什么时候要转给人工。
用 Claude Code 开发时,第一版应该尽量小。只回答十个高频问题,比做一个什么都想回答的助手更容易验证。范围越窄,测试越明确,成本越可控,也越容易把对话导向购买、咨询或培训。
架构表
| 层级 | 作用 | 生产环境注意点 |
|---|---|---|
| React UI | 输入、历史记录、加载状态和重试 | 状态管理可先参考 React useState 文档 |
| API 路由 | 在服务端保护 API key,并校验请求 | 增加长度限制、认证和超时 |
| Streaming | 边生成边返回,减少等待感 | Web Streams 的基础见 MDN Streams API |
| 会话存储 | 支持继续对话、审计和改进 | 只保存必要内容,并设计删除流程 |
| RAG | 从产品文档、政策或知识库中检索依据 | 没有可靠资料时不要编造答案 |
| Webhook | 把事件发送到 CRM、工单或 Slack | 可继续阅读 Claude Code Webhook Implementation |
| Analytics | 统计解决率、转人工率和 CTA 点击 | 可结合 Claude Code Analytics Implementation |
API 请求结构建议保持简单,参考 Claude Code API Development:前端只发送 role 和 content,系统提示词放在服务端,响应使用 stream 返回。这样以后要换 UI、增加移动端或调整模型,都不需要重写整套流程。
可直接运行的 streaming demo
把下面代码保存为 chatbot-stream-demo.mjs,执行 node chatbot-stream-demo.mjs。它不调用外部 API,只用于确认流式输出和会话历史的基本逻辑。
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const faq = new Map([
["password", "Open the account page, choose Reset password, and follow the email link."],
["pricing", "The pricing page explains plans. For a custom quote, collect team size and required features."],
["refund", "Refund requests should be routed to support with the order id and purchase email."],
]);
const history = [];
function chooseAnswer(question) {
const normalized = question.toLowerCase();
for (const [keyword, answer] of faq) {
if (normalized.includes(keyword)) return answer;
}
return "I could not find a safe answer in the FAQ. I will hand this to a human operator.";
}
async function* streamText(text) {
for (const token of text.split(/(\s+)/)) {
await new Promise((resolve) => setTimeout(resolve, 15));
yield encoder.encode(token);
}
}
async function ask(question) {
history.push({ role: "user", content: question });
const answer = chooseAnswer(question);
process.stdout.write(`\nUser: ${question}\nAssistant: `);
let fullAnswer = "";
for await (const chunk of streamText(answer)) {
const token = decoder.decode(chunk);
fullAnswer += token;
process.stdout.write(token);
}
history.push({ role: "assistant", content: fullAnswer });
}
await ask("How do I reset my password?");
await ask("Can I see pricing before talking to sales?");
console.log(`\n\nSaved ${history.length} messages.`);
上线时,把 chooseAnswer 换成 Claude API 调用即可。顺序不要变:先保存用户问题,再流式显示回答,最后保存完整回答。这样可以避免一个常见 failure mode:前端看起来已经输出了内容,但数据库里保存的是空回复。
真实 use case
第一个场景是 SaaS 售前咨询。机器人回答价格、安全、权限、集成方式等问题,当用户表现出明确购买意图时,再引导到咨询表单。这样销售团队不用反复回答基础问题,可以集中处理更有价值的线索。
第二个场景是公司内部 help desk。报销、请假、VPN、设备申请、入职流程都适合做成知识库问答。RAG 可以返回对应政策页面,必要时再通过 webhook 创建工单。
第三个场景是内容或课程网站。读者不知道下一步该学 API、Webhook 还是 Analytics 时,机器人可以推荐相关文章,并在需要实操帮助时引导到 training。这种 workflow 比直接弹广告自然,也更容易产生转化。
第四个场景是故障信息收集。机器人先问错误信息、时间、浏览器、账号和复现步骤,再把完整信息交给支持团队。这里的成功不是马上解决问题,而是减少来回追问。
具体坑点和风险
不要把无限长的聊天记录都发给模型。历史越长,成本越高,速度越慢,旧指令还可能干扰当前问题。更稳妥的做法是总结旧对话,只保留当前任务需要的事实。
不要让 RAG 在没有证据时强行回答。如果搜索结果很弱,机器人应该说明没有找到可靠资料,并提供人工咨询或工单入口。这个规则能减少很多错误承诺。
不要把 streaming 当成装饰。网络中断、重复点击、空消息气泡、加载状态不结束,都会让用户失去信任。第一版就要实现禁用按钮、取消请求、超时和重试提示。
不要没有数据就谈优化。至少要记录未解决问题、转人工、CTA 点击、以及哪些对话带来了购买或咨询。消息数量多不等于体验好,也不等于能赚钱。
变现 CTA
如果这个聊天机器人服务于商业网站,最后的行动要非常明确:预约咨询、实现审查、购买模板或参加培训。ClaudeCodeLab 推荐把高意向用户引导到 training,因为它能把阅读兴趣转成具体实施。
推荐阅读路径是:先在本文理解整体设计,再看 Claude Code API Development 搭建 API,用 webhooks 连接外部系统,最后用 analytics 评估转化效果。
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
把 Claude Code 变成真正能带来结果的工作流
先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。
相关文章
从Obsidian到CLAUDE.md的Claude Code流程:不再反复解释上下文
把 Obsidian 工作笔记整理成 CLAUDE.md 运行说明,让 Claude Code 每次都带着正确上下文开始。
Claude Code 收入 CTA 路由:从文章分流到 PDF、Gumroad 与咨询
用 Claude Code 按读者意图把文章流量分到免费 PDF、Gumroad 教材或咨询入口。
Claude Code 团队交接规则: 把审查证据、权限、回滚和收入路径一起交付
面向团队的 Claude Code 交接格式: 证据、权限、回滚、免费 PDF、Gumroad 与咨询路径都要可审查。