
LLM Zoomcamp Agentic RAG 实战用 ToyAIKit 框架替代手写 Agent 循环【免费下载链接】llm-zoomcampLLM Zoomcamp - a free online course about real-life applications of LLMs. In 10 weeks you will learn how to build an AI system that answers questions about your knowledge base. Register here 项目地址: https://gitcode.com/GitHub_Trending/ll/llm-zoomcamp本指南是 LLM Zoomcamp 2026 课程模块一「Agentic RAG」的进阶篇章。在上一课我们手工实现了一个while True的 Agent 循环本课引入教学框架 ToyAIKit用它把工具注册、Schema 生成、消息历史与模型调用循环全部封装起来让你聚焦于工具与 Prompt 本身。读完本文你将掌握如何用 ToyAIKit 的Tools、OpenAIResponsesRunner与LoopResult快速搭建一个具备拼写纠错、多轮检索与成本统计能力的 FAQ 问答 Agent并理解主流 Agent 框架背后共同的循环本质。为什么需要框架手写循环的重复劳动在上一课「The Agentic Loop」中我们亲手写下了 Agent 的核心循环调用模型、解析返回的函数调用、执行工具、把工具结果追加回消息历史然后重复直到模型不再请求工具。这段代码教学价值极高但它是重复的——每构建一个新的 Agent你都要重写同一个while True、同样的函数调用分发、同样的消息管理。ToyAIKit 正是为此而生它把这一模式封装成库让你把精力集中在**工具tools、提示词prompts和行为behavior**上而不是循环样板代码。它由 DataTalks.Club 的一次工作坊构建而成做的是和我们手写循环完全相同的事情只是样板更少。如果你打开它的runners源码会发现里面就是我们亲手写的那个while True循环。课程刻意选用 ToyAIKit是因为不想在众多生产级框架中选边站。ToyAIKit 小巧、易读出问题时你能清楚看到发生了什么非常适合在本地开发调试、在进入生产环境之前理解 Agent 的每个环节。⚠️ 一个重要的前提ToyAIKit 是教学与实验用库不适用于生产环境。课程使用它正是因为其极简、可读、透明。环境准备与安装使用uv一行命令安装uv add toyaikit然后导入需要用到的类from toyaikit.llm import OpenAIClient from toyaikit.tools import Tools from toyaikit.chat import IPythonChatInterface from toyaikit.chat.runners import OpenAIResponsesRunner, DisplayingRunnerCallbackOpenAIClient负责与 OpenAI Responses API 通信的 LLM 客户端Tools工具注册表管理所有可供 Agent 调用的函数IPythonChatInterface在 Notebook 中展示对话的界面OpenAIResponsesRunner真正运行 Agent 循环的 RunnerDisplayingRunnerCallback在循环执行时把模型消息和工具调用实时渲染出来的回调。把 search 函数注册为工具在函数调用一课中我们定义了顶层search函数它直接查询 FAQ 索引。结合课程仓库里的 rag_helper.py可以看到同样的检索参数在RAGBase.search()中定义boost_dict{question: 3.0, section: 0.5}提升问题字段权重filter_dict{course: llm-zoomcamp}把检索限定在本课程 FAQ 范围内索引本身则由 ingest.py 中的build_index()基于 minsearch 构建文本字段为question、section、answer关键字字段为course。注册工具时可以连同上一课手写的 schema 一起传入agent_tools Tools() agent_tools.add_tool(search, search_tool)这里的search_tool就是我们在函数调用一课手工写出的 JSON Schema——包含函数名search、描述 Search the FAQ database for entries matching the given query.以及必填参数query。模型看不到我们的 Python 代码只能通过这份 JSON 描述理解何时调用、传什么参数。让框架自动生成 Schema手工编写 Schema 既繁琐又易错而且每个函数都要写一份。好消息是——你根本不需要自己写。只要给search加上类型注解type hint和 docstringToyAIKit 就会读取它们并自动推导出 schemadef search(query: str) - dict[str, str]: Search the FAQ database for entries matching the given query. return index.search( query, num_results5, boost_dict{question: 3.0, section: 0.5}, filter_dict{course: llm-zoomcamp} )然后不传 schema 直接注册agent_tools Tools() agent_tools.add_tool(search)你随时可以查看框架生成了什么agent_tools.get_tools()输出正是我们在函数调用一课手工写的那份 JSON Schema——name、description、parameters.properties.query、required: [query]一应俱全完全由 docstring 和类型注解推导而来。这一魔法并非 ToyAIKit 独有。每一个现代 Agent 框架都在做同样的事读取一个带类型注解和 docstring 的 Python 函数然后据此构建工具描述。OpenAI Agents SDK、PydanticAI、LangChain 和 Google ADK 都是如此工作——你只负责写工具框架负责如何描述它。Chat 界面与 Runner框架替你跑 Agent 循环创建聊天界面和回调然后组装 Runnerchat_interface IPythonChatInterface() callback DisplayingRunnerCallback(chat_interface) runner OpenAIResponsesRunner( toolsagent_tools, developer_promptinstructions, chat_interfacechat_interface, llm_clientOpenAIClient(modelgpt-5.4-mini) )各部分职责分明chat_interface负责 Notebook 中的展示callback在模型消息和工具调用发生时实时渲染它们runner运行整个 Agent 循环——就是我们在上一课亲手写的那个while True发送消息、执行函数调用、把工具输出追加回去、重复直到模型认为可以结束developer_prompt传入的是「The Agentic Loop」一课中的instructions——那份你是课程助教、尽量用用户问题中的关键词发起首次检索、做多次搜索、结束时询问用户是否想探索其他方向的角色设定。Prompt 写得越好Agent 帮得越好。这里刻意选择gpt-5.4-mini如果不指定模型ToyAIKit 会回退到默认的、更小更快的模型而那个默认模型对指令的遵循不够可靠。显式指定模型可以保证 Agent 行为符合预期。运行单次 Prompt观察拼写错误的自动恢复运行单个提示词result runner.loop( promptHow do I run Olama locally?, callbackcallback, )这里的 Olama 是故意写错的拼写。整个 Agentic RAG 模块的核心动机就在于此在「Agents」入门课中我们看到固定管线遇到拼写错误时检索一无所获、LLM 无从恢复而 Agent 模式下模型会先搜 Olama 得到糟糕结果再自行重试 Ollama 并找到答案——这个恢复过程与手写循环完全一致只是 Notebook 输出更漂亮每次工具调用和消息都内联渲染你可以逐条查看每一次搜索结果。返回值result是一个LoopResult对象包含all_messages完整对话记录token 计数本次循环消耗的输入/输出 tokencost根据 token 用量计算出的费用。成本与 Token开发期的预算监控直接查看这次调用的花费result.cost这在开发期非常有用尤其是多轮 Agent——一个 prompt 可能触发多次模型调用。回顾函数调用一课当时我们用calculate_gpt54mini_price()手动把 token 换算成美元还要注意每次调用都会把完整历史作为输入重发、费用逐轮累积。手写循环需要你自己逐次累加而框架会为你在LoopResult里维护一个持续累加的总数。同样可以查看完整消息历史result.all_messages它就是一个列表——正是我们在手写循环里自己维护的那个messages列表只是现在由 Runner 帮你追加每一条模型输出、函数调用和工具结果。多轮对话携带 previous_messages 继续把上一轮结果中的消息作为previous_messages传给下一次loop调用即可无缝续接对话result2 runner.loop( promptHow do I run a different model?, previous_messagesresult.all_messages, callbackcallback, )Runner 会从上次调用的位置继续使用同一个 Agent 循环、扩展后的历史记录。模型之所以知道different model指的是 Ollama正是因为它在记忆中看到了上一轮的对话内容——如果没有这段历史它完全不知道你在问什么。这正是 Agent 三要素之一Memory消息历史的体现每一个 prompt、每一条模型输出、每一次工具结果都被追加进历史Agent 借此知道它已经尝试过什么。交互式聊天runner.run()如果要做聊天式工作流直接运行内置的输入循环runner.run()输入问题即可获得回答输入 stop 退出。这个交互模式把同一套 Runner 从单次实验切换到持续对话适合在 Notebook 里快速体验完整的助教式问答体验。框架之外从教学到生产ToyAIKit 的价值在于透明因为小而可读当它出问题时你能看透每个环节。这也让它成为理解框架替你隐藏了什么的最佳教材——正如「The Agentic Loop」一课结尾所说每个 Agent 框架都封装着同一个模式无论 LangChain、PydanticAI 还是 OpenAI Agents SDK。当你要走向生产环境时课程在「Other Frameworks」一课给出了候选清单OpenAI Agents SDK官方、基于同一套 Responses API、PydanticAI类型安全、多供应商、LangChain/LangGraph集成丰富、支持图式工作流、Google ADK面向 Gemini 与 Google Cloud以及 CrewAI、AutoGen、Semantic Kernel、Smolagents、Anthropic Tool Use 等。它们的循环都一样难的是设计好工具与 Prompt。最后记得并非所有问题都需要 Agent。Agent 意味着更多 API 调用、更高延迟、更多成本、更多可监控的环节与更不可预测的行为。先尝试普通 RAG、文档解析或单次无工具 LLM 调用——如果简单方案可行就交付它只有当简单方案确实无法胜任时再引入 Agent 循环。到那时你已经理解了循环的本质也准备好了承担这份复杂度。本课全文对应的可运行代码与索引构建脚本可分别参考 code/rag_helper.py 与 code/ingest.py整个模块的课程脉络见 01-agentic-rag 模块首页。【免费下载链接】llm-zoomcampLLM Zoomcamp - a free online course about real-life applications of LLMs. In 10 weeks you will learn how to build an AI system that answers questions about your knowledge base. Register here 项目地址: https://gitcode.com/GitHub_Trending/ll/llm-zoomcamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考