从 0 到 1 搭一个能『自己查资料』的 AI 智能体一篇能照着做、做完就能跑起来的实战教程。所有数据都在你电脑上。一、为什么是 AgentScope智能体开发框架现在很多LangChain、LlamaIndex、AutoGen、CrewAI……如果你需要开箱即用的 ReAct 范式思考-行动-观察循环官方内置知识库抽象KnowledgeBaseQdrantStore不写 prompt 模板也能让模型自动调用工具AgentScope 2.0.x 是一个很好的选择。它是蚂蚁集团开源的多智能体框架Python API 设计现代async-first、ContentBlock 列表、统一的 Credential 管理文档和示例中文友好。这次要做的事情用一句话概括给 AI 一本技术字典让它回答用户问题前自己翻字典引用出处再作答。下面从环境到 UI 一层层拆开全程可复现。二、整体架构项目分四个模块对应 4 个核心文件模块文件职责配置层config.py读 .env构造对话模型、嵌入模型、向量库知识库ingest.py把 5 篇技术文章切片、嵌入、写入 Qdrant智能体agent.py把检索能力封装成FunctionTool挂到 ReAct AgentUIserver.pystatic/index.htmlPython 标准库 SSE 后端 自建前端四个文件不到 600 行代码跑通完整 RAG 链路。数据流用户提问│▼[前端 /api/chat SSE]│▼agent.reply_stream()│ ┌──────────────────────────────────────┐├─►│ Thought思考 │──► SSE: thinking│ ├──────────────────────────────────────┤├─►│ Action调 search_knowledge_base 工具 │──► SSE: tool│ │ ┌──────────────────────────┐ ││ │ │ knowledge_base.search() │ ││ │ │ ↓ Qdrant 向量检索 │ ││ │ │ ↓ DashScope 实时嵌入 │ ││ │ └──────────────────────────┘ ││ ├──────────────────────────────────────┤├─►│ Observation检索结果 │──► SSE: sources│ ├──────────────────────────────────────┤└─►│ Final Answer基于结果作答 │──► SSE: token...│ └──────────────────────────────────────┘▼前端流式渲染token 实时显示、sources 折叠到回答下方三、阶段 0环境准备# 建隔离 venvpython -m venv .venv.venv\Scripts\activate# 安装依赖pip install agentscope2.0.4 qdrant-client python-dotenv确认版本python -c import agentscope; print(agentscope.__version__)# → 2.0.4.env配置# 对话模型DeepSeekDEEPSEEK_API_KEYsk-...DEEPSEEK_BASE_URLhttps://api.deepseek.comCHAT_MODEL_NAMEdeepseek-v4-flash# 嵌入模型通义 DashScopeEMBEDDING_PROVIDERdashscopeDASHSCOPE_API_KEYsk-...DASHSCOPE_EMBEDDING_MODELtext-embedding-v3DASHSCOPE_EMBEDDING_DIMENSIONS1024# 向量库本地嵌入式零运维QDRANT_PATH./qdrant_db关于模型选型DeepSeek 目前只提供对话接口没有 embedding 端点AgentScope 2.0.4 也不内置DeepSeekEmbeddingModel。所以嵌入层选择 DashScope 的text-embedding-v31024 维对中文支持好、有免费额度。如果你偏好本地部署也可以换成 Ollama 的嵌入模型AgentScope 有OllamaEmbeddingModel。Qdrant 文件锁本地 path 模式下同一个./qdrant_db目录不能同时被两个进程打开。开发时注意ingest.py和后续脚本不要并行运行。四、阶段 1知识库构建4.1 语料corpus/下放 5 篇中文技术文章.md格式每篇覆盖一个智能体子主题corpus/├── 01-react-推理行动范式.md├── 02-rag-检索增强生成.md├── 03-工具调用与function-calling.md├── 04-多智能体协作.md└── 05-智能体记忆机制.md4.2 ingestion 管线AgentScope 2.0.4 的KnowledgeBase将解析器、分块器、向量库、嵌入模型都拆成可插拔组件。完整的ingest.pyfrom agentscope.rag import TextParser, ApproxTokenChunkerfrom config import build_knowledge_baseasyncdefingest(reset: bool False) - None:kb build_knowledge_base(nameagent_dev_kb,description智能体开发技术知识库,collectionagent_dev_articles,)parser TextParser()chunker ApproxTokenChunker(chunk_size512, overlap50)await kb.ensure_collection()if reset:for doc inawait kb.list_documents():await kb.delete_document(doc.document_id)for fp insorted(CORPUS_DIR.glob(*.md)):content fp.read_text(encodingutf-8)sections await parser.parse(content, fp.name) # 1. 解析chunks await chunker.chunk(sections) # 2. 分块await kb.insert_document( # 3. 嵌入 入库chunks,document_idfp.stem,document_metadata{filename: fp.name},)三步 APIparse→chunk→insert_document全部 async。注意检索结果hit.chunk.content的类型是TextBlock 对象或 TextBlock 列表不是str。取文本时需做类型判断def block_text(c):if c isNone: returnifisinstance(c, str): return cifisinstance(c, list):return\n.join(b.text ifhasattr(b, text) elsestr(b) for b in c)returngetattr(c, text, str(c))执行导入python ingest.py --reset预期输出[ok] 01-react-推理行动范式.md - 4 chunks[ok] 02-rag-检索增强生成.md - 3 chunks...导入完成5 个文档共 15 个 chunk五、阶段 2检索增强 Agent核心思路把知识库检索封装成一个FunctionTool让 Agent 在 ReAct 循环中自主决定何时检索、检索什么。5.1 FunctionTool 封装from agentscope.tool import FunctionToolasyncdef_search_knowledge_base(query: str, top_k: int 5) - str:在智能体开发知识库中检索与问题相关的文档片段。kb build_knowledge_base(KB_NAME, KB_DESC, COLLECTION)results await kb.search(query, top_ktop_k)docs []for h in results:text block_text(getattr(h.chunk, content, None))src (h.chunk.metadata or {}).get(filename, 未知文档)score float(getattr(h, score, 0.0) or0.0)docs.append({source: src, score: score, text: text})global _last_sources_last_sources.extend(docs)ifnot docs:return未在知识库中找到相关内容。return\n\n.join(f[{i}] 来源《{d[source]}》相关度 {d[score]:.2f}\n{d[text]}for i, d inenumerate(docs, 1))retrieval_tool FunctionTool(func_search_knowledge_base,namesearch_knowledge_base,description(在「智能体开发技术知识库」中检索相关文档片段。当用户询问 Agent / 智能体、ReAct、RAG、工具调用、Function Calling、多智能体协作、记忆机制等开发相关问题时使用本工具获取权威资料。),)description写得越具体、给的使用场景越多模型主动调用工具的概率越高。5.2 构造 ReAct Agentfrom agentscope.agent import Agent, ReActConfigfrom agentscope.tool import Toolkitfrom agentscope.state import AgentStatefrom agentscope.permission import PermissionContext, PermissionModedef_build_agent() - Agent:model get_chat_model()toolkit Toolkit(tools[retrieval_tool])react_config ReActConfig(max_iters5)state AgentState(permission_contextPermissionContext(modePermissionMode.BYPASS),)return Agent(nameagent_dev_assistant,system_prompt_SYSTEM_PROMPT,modelmodel,toolkittoolkit,react_configreact_config,statestate,)权限要点ReAct 的默认权限模式是REQUIRE_USER_CONFIRM这会导致每次工具调用前等待人工确认循环不会自动推进。对只读的检索工具用PermissionMode.BYPASS让 Agent 自主执行。注意不要把这个模式用于有副作用写操作、网络请求修改状态的工具。5.3 流式事件消费AgentScope 2.0.4 的流式接口async for evt in agent.reply_stream(user_msg):t str(getattr(evt, type, )).lower()if t text_block_delta: yield (token, evt.delta)elif t thinking_block_delta: yield (thinking, evt.delta)elif t tool_call_start: yield (tool, evt.tool_call_name)事件type字段是大写字符串TEXT_BLOCK_DELTA、THINKING_BLOCK_DELTA、TOOL_CALL_START比对前先.lower()。stream_reply生成器在结束时 yield(sources, deduped)(done, None)供 UI 区分正在生成和生成完毕。六、阶段 3UI 层Agent 写好后用命令行交互当然可以跑。但要做展示或分享一个好看的可视化界面会让体验完全不同。这里没有使用 Gradio——它的默认样式定制空间有限视觉效果比较单调。取而代之的是Python 标准库 自建前端的组合层选型说明后端http.server.ThreadingHTTPServerPython 自带零额外依赖协议Server-Sent EventsSSE单向流比 WebSocket 简单前端用fetchReadableStream直接消费前端单文件index.html内联 CSS/JS零构建步骤6.1 后端server.py整个server.py不到 200 行。关键设计用后台 daemon 线程运行一个持久事件循环所有对话请求通过run_coroutine_threadsafe提交。import asyncio, json, threadingfrom http.server import BaseHTTPRequestHandler, ThreadingHTTPServer# 持久事件循环AgentScope 的流式生成器依赖长期存活的 loop_LOOP asyncio.new_event_loop()def_run_loop():asyncio.set_event_loop(_LOOP)_LOOP.run_forever()threading.Thread(target_run_loop, daemonTrue).start()classHandler(BaseHTTPRequestHandler):defdo_POST(self):ifself.path /api/chat:self.send_response(200)self.send_header(Content-Type, text/event-stream)self.end_headers()fut asyncio.run_coroutine_threadsafe(pump(), _LOOP)fut.result(timeout180)设计决策说明为什么用持久 loop 而不是每请求新建AgentScope 内部Agent._reasoning、httpxAsyncStream维护的异步任务生命周期跨越整个 ReAct 循环。每次请求新建 销毁 loop 会导致流式协程在中途挂起。用一个 daemon 线程跑run_forever()的持久 loop和 Gradio 内部 uvicorn 的行为一致。API 接口GET /api/stats— 知识库统计文档数、就绪状态POST /api/reset— 清空多轮对话历史POST /api/chat— SSE 流事件类型token/thinking/tool/sources/done/error其他几个容易忽略的细节服务器绑0.0.0.0而非127.0.0.1。Windows 上部分浏览器把localhost解析为 IPv6::1只绑 IPv4 地址会导致连接被拒、前端报 failed to fetch/api/stats内部的异步调用也要走run_coroutine_threadsafe不能直接在已运行run_forever()的 loop 上调run_until_complete确保用项目 venv 的 Python 启动而非系统或托管 Python否则会缺少agentscope/qdrant_client等包6.2 前端index.html设计目标看得像专业聊天产品同时保持代码简洁单文件、零依赖。侧边栏288px 固定宽度渐变品牌 logo 应用描述知识库状态卡文档数 / 对话模型 / 向量模型建议问题 chips点击自动填入并发送深色/浅色切换localStorage 持久化清空对话主聊天区用户气泡右对齐紫色渐变背景助手气泡左对齐白色卡片带渐变头像流式阶段逐 token 显示文本 闪烁光标done后整体渲染 markdown检索中状态顶部状态栏显示正在检索知识库 · search_knowledge_basemarkdown 渲染流式阶段用renderMdLive实时渲染自动给未闭合的代码块补上防止布局抖动支持标题h1-h3、粗体、行内代码、代码块带语言标注、有序/无序列表、引用、表格、链接仅允许 http(s) 或相对路径其余降至#。表格检测到|...|行时缓冲遇到非表格行 flush——自动识别表头行 分隔行|---| 数据行CSS 带斑马纹。参考来源用原生details元素折叠每条显示文件名、相关度分数、进度条分数 × 100%、180 字片段预览和展开全文切换。深色模式CSS 自定义属性 data-theme切换两套完整的颜色变量。响应式窄于 860px 时侧边栏变为抽屉面板汉堡按钮 半透明遮罩。整个前端一个文件约 500 行 CSS 300 行 JS。七、技术要点汇总#要点操作1DeepSeek 无 embedding 接口嵌入层选 DashScope或 Ollama 本地2Qdrant path 模式有文件锁避免多进程同时访问同一目录3chunk.content是 TextBlock 列表取文本用block_text()做类型判断4ReAct 默认权限会暂停等待确认只读工具设PermissionMode.BYPASS5流式事件 type 是大写字符串比对前先.lower()6AgentScope 流式依赖持久事件循环后台 daemon 线程 run_coroutine_threadsafe7/api/stats不能在已运行的 loop 上调run_until_complete统一用run_coroutine_threadsafe8服务器绑127.0.0.1可能被 IPv6 跳过绑0.0.0.09用错 Python 解释器会导致包找不到始终用 venv 的 python.exe八、跑起来# 1. 环境python -m venv .venv.venv\Scripts\activatepip install -r requirements.txtcp .env.example .env # 填入 DEEPSEEK_API_KEY、DASHSCOPE_API_KEY# 2. 灌库python ingest.py --reset# 3. 启动python server.py# → http://localhost:8000打开浏览器即可使用提问、看流式回答、展开来源引用、切换主题。九、接下来可以做什么这个版本已经完整跑通 RAG ReAct 范式以下是可以继续增强的方向查询改写用户口语化问题先让 LLM 重写成更适合检索的关键词组命中率会明显提升Reranker检索 Top-5 后用小模型重排如 bge-reranker-v2答案质量上一档流式工具结果把工具返回从一次性的整段文本改成边检索边输出的细粒度流多轮对话压缩长对话超出 token 上限时用 sliding window 或自动摘要裁剪上下文权限分级把 BYPASS 拆成只读 / 可写的两套权限写操作保留人工确认多知识库把不同领域的文档放入独立知识库让 Agent 根据问题自动路由到对应知识库这些扩展点都在 AgentScope 2.0.4 的原生支持范围内不需要改框架就能做到。技术栈AgentScope 2.0.4 / DeepSeek-v4-flash / DashScope text-embedding-v3 / Qdrant (本地嵌入式) / Python 3.13 / 零额外 UI 依赖代码量~600 行 Python ~800 行 HTML/CSS/JS