从零手写 AI Agent:一个本地知识库助手的完整实现(Python + DeepSeek)
前言最近 AI Agent 这个概念火得不行各种框架LangChain、CrewAI、AutoGen层出不穷。但我发现很多新手一上来就啃框架源码结果被各种抽象层绕晕了。其实Agent 的核心原理非常简单——就是一个 while 循环。你完全可以从零手写一个不超过 200 行代码。这篇文章带你从零实现一个本地知识库 AI Agent它能自动搜索、阅读、整理你的 Markdown 笔记。全程 Python调用 DeepSeek API没有任何框架依赖。 完整代码已开源GitHub - Hao-max1/knowledge-agent · GitHub一、什么是 Agent1.1 普通 LLM vs Agent普通 ChatGPT 是一问一答你: 11等于几 AI: 2 → 结束Agent 是多轮思考你: 帮我找关于 Python 的笔记 AI: [思考] 用户想找笔记 → 我先搜一下 → 调用 search_notes(Python) ← 第一次 API 调用 → 结果: python-basics.md ​ AI: [再思考] 搜到了但用户想要内容 → 读一下 → 调用 read_note(python-basics.md) ← 第二次 API 调用 → 结果: 文件内容是... ​ AI: [最终] 拿到了可以回答了 → 你的笔记里讲了 Python 基础包括... ← 最终回复Agent LLM 工具 循环。就这么简单。1.2 为什么需要循环因为 LLM不知道工具的执行结果。它只能说我想用工具 X然后停下来等你执行。你把结果喂回去它才能继续思考。二、项目结构knowledge-agent/ ├── main.py # CLI 入口 ├── agent.py # ★ 核心Agent 循环 ├── tools.py # 工具定义 执行 ├── config.py # 配置加载 ├── requirements.txt # 仅 2 个依赖 ├── .env # API Key └── knowledge_base/ # 你的笔记目录技术选型项目选择理由语言Python 3.9生态最好LLM APIDeepSeekdeepseek-chat便宜、支持 tool calling、OpenAI 兼容SDKopenai标准 SDKDeepSeek 完全兼容存储本地 Markdown 文件零依赖即开即用依赖openai1.0.0 python-dotenv1.0.0仅两个依赖极简。三、核心代码Agent 循环这是整个项目的心脏agent.py里的核心逻辑核心 Agent 循环 — 思考 → 行动 → 观察 → 再思考 ​ import json from openai import OpenAI from config import DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL, MODEL, MAX_TOOL_ROUNDS from tools import TOOL_SCHEMAS, execute_tool ​ client OpenAI(api_keyDEEPSEEK_API_KEY, base_urlDEEPSEEK_BASE_URL) ​ SYSTEM_PROMPT 你是一个知识库助手 Agent帮助用户管理和检索笔记。 ​ ## 你的能力 - search_notes搜索包含关键词的笔记 - list_notes列出知识库中所有笔记 - read_note读取一篇笔记的完整内容 - write_note创建或更新一篇 Markdown 笔记 ​ ## 工作方式 1. 理解用户需求 2. 先搜索再阅读 —— 不要猜测文件内容 3. 基于实际内容回答不要编造 4. 用中文回复 ​ ​ def run_agent(user_query: str, on_tool_callNone) - str: 执行一次 Agent 对话。 # messages 就是 Agent 的记忆 messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_query}, ] ​ # ★ Agent 循环 for round_num in range(1, MAX_TOOL_ROUNDS 1): # ① 调用 LLM response client.chat.completions.create( modelMODEL, messagesmessages, toolsTOOL_SCHEMAS, temperature0.1, ) ​ choice response.choices[0] msg choice.message ​ # ② 判断LLM 说完了还是想调工具 if choice.finish_reason stop: return msg.content or 未返回回复 ​ elif choice.finish_reason tool_calls: # ③ 把 LLM 的回复加入记忆 messages.append(msg.to_dict()) ​ # ④ 执行每个工具调用 for tc in msg.tool_calls: tool_name tc.function.name tool_input json.loads(tc.function.arguments) ​ if on_tool_call: on_tool_call(tool_name, tool_input) ​ result execute_tool(tool_name, tool_input) ​ # ⑤ 把工具结果加入记忆 messages.append({ role: tool, tool_call_id: tc.id, content: result, }) ​ # ⑥ 循环继续LLM 看到结果后会再次思考 ​ return [WARNING] Agent 达到最大思考轮次。流程图用户输入 │ ▼ ┌─────────────────────┐ │ LLM 思考 │ ← chat.completions.create() │ (带上全部历史消息) │ └──────┬──────────────┘ │ ├─ finish_reasonstop ──→ 返回回复给用户 │ └─ finish_reasontool_calls │ ▼ ┌──────────────┐ │ 执行工具 │ ← execute_tool() └──────┬───────┘ │ ▼ ┌──────────────┐ │ 把结果加入 │ ← messages.append() │ messages │ └──────┬───────┘ │ └──→ 回到开头继续循环四、工具定义工具是 Agent 的手。用 JSON Schema 定义LLM 通过description字段理解每个工具该什么时候用。# tools.py — 以 search_notes 为例 ​ TOOL_SCHEMAS [ { type: function, function: { name: search_notes, description: ( 在知识库中搜索包含指定关键词的笔记文件。 当用户问「有没有关于XX的笔记」「帮我找XX」时使用此工具。 ), parameters: { type: object, properties: { query: { type: string, description: 搜索关键词, }, }, required: [query], }, }, }, # ... list_notes, read_note, write_note ]关键点description非常非常重要它决定了 LLM 能不能在正确的时机调用工具。写得太笼统如用来搜索LLM 可能不知道该什么时候用。工具执行是纯 Python 文件操作def _search_notes(query: str) - str: 遍历知识库搜索包含关键词的文件。 query_lower query.lower() results [] ​ for root, dirs, files in os.walk(KNOWLEDGE_BASE): for fname in files: if not fname.endswith((.md, .txt)): continue content Path(root, fname).read_text(encodingutf-8) if query_lower in content.lower(): # 提取匹配行作为摘要 matching_lines [ line.strip() for line in content.split(\n) if query_lower in line.lower() ] results.append(f[文件] {fname}\n {matching_lines[:5]}) ​ return f找到 {len(results)} 篇:\n \n\n.join(results) if results \ else f未找到「{query}」相关笔记。五、安全设计5.1 路径逃逸防护LLM 是不可控的万一它尝试../../etc/passwd呢def _safe_path(relative_path: str) - Path: 确保 LLM 无法访问知识库外的路径。 full (KNOWLEDGE_BASE / relative_path).resolve() if not str(full).startswith(str(KNOWLEDGE_BASE.resolve())): raise ValueError(f不允许访问知识库外的路径: {relative_path}) return full5.2 防死循环MAX_TOOL_ROUNDS 10Agent 最多调用 10 轮工具后强制中断。六、Anthropic vs DeepSeek 对比我最初用的是 Claude API后来换成 DeepSeek。Agent 循环逻辑完全没变只是 API 格式不同项目Anthropic (Claude)DeepSeekSDKimport anthropicfrom openai import OpenAI调用方法client.messages.create()client.chat.completions.create()工具格式namedescriptioninput_schematype:functionfunction:{...}结束标志stop_reason end_turnfinish_reason stop工具调用标志stop_reason tool_usefinish_reason tool_calls工具参数block.input直接是 dictjson.loads(tc.function.arguments)结果回传role:usertype:tool_resultrole:toolSystem Prompt独立参数system...messages[0],role:system核心收获Agent 的灵魂是你写的循环逻辑不是某个具体的 API。换一家 LLM 只需改 API 调用格式循环不动。七、效果演示$ python main.py ╔══════════════════════════════════════════╗ ║ 知识库 AI Agent ║ ╠══════════════════════════════════════════╣ ║ 模型: deepseek-chat ║ ║ 知识库: .../knowledge_base ║ ║ 工具: search_notes, list_notes, ... ║ ╚══════════════════════════════════════════╝ 帮我找关于 Python 的笔记 Thinking... Tool: search_notes(queryPython) ← Agent 自动搜索 Tool: read_note(file_pathpy.md) ← Agent 自动读取 你的知识库中有一篇关于 Python 的笔记内容摘要如下 - Python 是一门解释型语言 - 语法简洁适合初学者 - 广泛应用于数据科学、Web 开发、自动化脚本等领域 帮我写一篇 Git 常用命令的笔记 Thinking... Tool: write_note(file_pathgit.md, content...) ← Agent 自动创建 [OK] 笔记已保存: git-cheatsheet.md856 字符八、如何扩展学完基础后你可以加工具网页搜索、天气查询、发邮件——在tools.py里加定义 实现即可加记忆把对话历史存到 SQLite下次启动恢复实现跨会话记忆加流式输出streamTrue让 LLM 回复逐字显示换 MCP 协议把工具标准化为 MCP Server其他 Agent 也能用做 Web UI用 Streamlit 或 Gradio 包一层网页界面加上 RAG引入向量数据库实现语义搜索九、总结AI Agent 开发不需要从啃框架开始。核心就三样东西Agent LLM 工具 while 循环理解了这三样什么 LangChain/CrewAI/AutoGen不过是在这个基础上加了更多抽象。建议的学习路径先用起来用 Claude Code、Cursor 等体验 Agent 能做什么手写一个像本文一样50-200 行代码写一个最小 Agent加复杂度多工具、记忆、流式输出回头看框架这时候你才能真正理解框架的价值纸上得来终觉浅绝知此事要躬行。直接动手吧。完整代码项目地址https://github.com/Hao-max1/knowledge-agent直接把代码拷到本地改.env里的 API Key 就能跑git clone https://github.com/Hao-max1/knowledge-agent.git cd knowledge-agent cp .env.example .env # 编辑 .env 填入你的 DeepSeek API Key pip install -r requirements.txt python main.py如果这篇文章对你有帮助欢迎点赞、收藏、关注。有问题可以在评论区留言交流。

相关新闻

DeepSeek V4 + Pixso AI实测:一套AI生成图片和UI稿的新流程

DeepSeek V4 + Pixso AI实测:一套AI生成图片和UI稿的新流程

如果让AI深度参与到产研里,生成代码和UI稿能变简单吗?最近我尝试了一套全新的组合工作流:用 DeepSeek V4 负责理解需求和拆解逻辑,用 Pixso AI 负责生成视觉方案和具体的设计稿。效果还行,分享下具体怎么用的。一、Dee…

2026/7/23 13:26:27 阅读更多 →
UE5蓝图实现GPU Instancing:动态海量物体渲染与性能优化指南

UE5蓝图实现GPU Instancing:动态海量物体渲染与性能优化指南

1. 项目概述:为什么我们需要蓝图驱动的GPU Instancing?如果你在UE5里做过需要大量重复物体的场景,比如一片随风摇曳的草地、一片茂密的森林、或者城市里熙熙攘攘的人群,那你一定体会过手动摆放的痛苦。一个一个拖拽Actor到场景里&…

2026/7/23 13:25:27 阅读更多 →
小安派工:售楼部弱电工程施工,隐蔽工程处理技巧

小安派工:售楼部弱电工程施工,隐蔽工程处理技巧

一、售楼部弱电隐蔽工程施工特点与难点售楼部属于展示型商业空间,包含安防监控、背景音乐、大屏显示、无线网络、门禁、访客系统、灯光联动等多套弱电系统。装修档次要求高,外立面、墙面、吊顶尽量减少明线外露,绝大多数线缆需要采用隐蔽敷设…

2026/7/23 13:25:27 阅读更多 →

最新新闻

遗传算法优化BP神经网络的MATLAB实现与应用

遗传算法优化BP神经网络的MATLAB实现与应用

1. 项目概述在工程预测和数据分析领域,神经网络因其强大的非线性拟合能力而广受青睐。然而,传统神经网络(尤其是BP神经网络)存在训练速度慢、易陷入局部最优等固有缺陷。遗传算法作为一种模拟自然进化过程的全局优化方法&#xff…

2026/7/23 13:39:38 阅读更多 →
制造业经验数字化:从老师傅手感U盘存储到AR传承

制造业经验数字化:从老师傅手感U盘存储到AR传承

1. 为什么需要把经验装进U盘 在制造业和传统手工业领域,老师傅们积累了数十年的宝贵经验。这些经验往往以"手感"、"火候"、"眼力"等形式存在,难以量化传承。我曾亲眼见证一位退休的老钳工,仅凭手指触摸就能判断…

2026/7/23 13:39:38 阅读更多 →
创新:层层引爆效应

创新:层层引爆效应

创新落地从来不是单点发力就能实现的,它需要一套环环相扣的链式传导机制,而搭建创新选择层级传导整合模型,正是破解创新落地难题的关键。很多时候,我们没能清晰定位自身在创新推进中的角色,导致创新难以从构想转化为实…

2026/7/23 13:39:38 阅读更多 →
双分支残差网络在低光照图像增强中的应用与实践

双分支残差网络在低光照图像增强中的应用与实践

1. 项目背景与核心挑战低光照图像增强是计算机视觉领域长期存在的技术难题。在安防监控、医疗影像、自动驾驶等实际场景中,由于光照条件限制获取的图像往往存在噪声大、细节丢失、色彩失真等问题。传统方法如直方图均衡化、Retinex理论等基于人工设计的特征提取方式…

2026/7/23 13:39:38 阅读更多 →
OEM贴牌会不会影响GEO获客效果

OEM贴牌会不会影响GEO获客效果

这是贴牌方在决策时的一个核心疑虑:系统打上自己的品牌后,GEO的获客效果会不会打折扣?毕竟在传统制造业中,“贴牌”有时意味着“技术降级”。这个担忧在软件OEM领域是完全不需要的。OEM贴牌不影响获客效果的底层逻辑AI搜索平台在评…

2026/7/23 13:39:38 阅读更多 →
jdk8 list 删除500行开始的数据

jdk8 list 删除500行开始的数据

在 JDK 8 中,要从 List 中删除从第 500 行开始的所有数据(即删除索引 > 499 的所有元素),有多种方式。根据你的具体需求,我整理了几种常用方法:一、删除从第 500 行开始到末尾的所有数据方法一&#xff…

2026/7/23 13:38:38 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 12:54:44 阅读更多 →

月新闻