编程 不装 LangChain:用 Groq API 手写吴恩达定义的四种 Agentic 模式

2026-09-29 00:03:42

不装 LangChain:用 Groq API 手写吴恩达定义的四种 Agentic 模式

吴恩达在 DeepLearning.AI 的 Agentic AI 课程里给过一个定义:Agentic AI 是一种新的软件构建方式,用 LLM 完成复杂任务的若干或全部步骤。区别在于,不再是单次 prompt 换一个回答,而是让模型规划多步流程、迭代执行,并通过 reflection 与 tool use 改进输出。课程的主张是先「从第一性原理用 Python 实现每个模式」,再引入框架。

课程定义的四种设计模式:

  • Reflection(反射):AI 批判自己的工作并迭代提升质量,相当于自动化的 code review。
  • Tool Use(工具使用):把 AI 接到数据库、API、外部服务,让它真的执行动作,而不只是生成文本。
  • Planning(规划):把复杂任务拆成可执行步骤,任务不按预期走时能调整。
  • Multi-Agent(多智能体):协调多个专用 AI 系统处理复杂工作流的不同部分。

课程还覆盖性能指标、错误分析、生产部署,目标是把业务流程拆解成 agentic workflow。

  • 课程页面:https://www.deeplearning.ai/courses/agentic-ai
  • 四种模式的原始定义(The Batch 博文):https://www.deeplearning.ai/the-batch/how-agents-can-improve-llm-performance/
  • 学员课程仓库:https://github.com/madeeha96/agentic-ai 、https://github.com/nhatnam2609/agentic_ai_andrew

课程 lab 的实际分布大致是:Module 1 做 planner→research→writer→editor 的多步工作流,工具接 Tavily 搜索、arXiv、Wikipedia API,配 FastAPI + Postgres + Docker;Module 2 的 Reflection 有 flashcards agent、PII removal(防御性反射)、SQL agent 自纠正、可视化图表迭代,并对比 reasoning 模型与通用模型做 reflection 的效果;Module 3 的 Tool Use 走 OpenAI function calling 与 AISuite 两条路,包含 email agent(FastAPI)、动态 schema 探索的 SQL agent,并介绍 MCP;Module 5 的多智能体是 Planner→Coder→Executor→Reflector 的客服流水线,讲错误恢复与自纠正,以及线性序列与并发对话的取舍,最终项目是 planning agent 协调研究、写作、编辑。

项目信息

如果不想被框架的抽象层挡住,可以直接看这个仓库:

  • 仓库地址:https://github.com/neural-maze/agentic_patterns

README 的原话是:No LangChain, no LangGraph, no LlamaIndex, no CrewAI. Pure and simple API calls to Groq. 它把吴恩达博文系列里定义的 4 个 agentic pattern 逐个实现出来,目的是理解底层机制并用于教学,README 也明确写了「这是教学项目,不是 agentic 框架」。

安装两种方式:

poetry install
# 或
pip install -U agentic-patterns

LLM provider 用 Groq,需要自己建 API Key,写进 .env 的 GROQ_API_KEY。

代码结构上,src/ 下四个模式各占一个子包:reflection_pattern/reflection_agent.py、tool_pattern/{tool.py,tool_agent.py}、planning_pattern/react_agent.py、multiagent_pattern/{agent.py,crew.py};notebooks/ 下每个模式配一个逐步讲解的 notebook。

Reflection

from agentic_patterns import ReflectionAgent

agent = ReflectionAgent()
generation_system_prompt = "You are a Python programmer tasked with generating high quality Python code"
reflection_system_prompt = "You are Andrej Karpathy, an experienced computer scientist"

user_msg = "Generate a Python implementation of the Merge Sort algorithm"

final_response = agent.run(
    user_msg=user_msg,
    generation_system_prompt=generation_system_prompt,
    reflection_system_prompt=reflection_system_prompt,
    n_steps=10,
    verbose=1,
)
print(final_response)

两个 system prompt 分别扮演生成者和评审者,n_steps 控制生成—评审—修正的迭代轮数。

它解决的问题是单次生成的质量上限:同一份代码被一个「更挑剔的角色」再读一遍,问题暴露得更早。边界也在这里——迭代轮数上去,token 成本线性上涨,而收益通常在几轮后就趋于平坦;如果任务本身没有客观对错(开放式写作、主观设计),评审者容易把内容改成四平八稳的版本。这类任务不建议上 Reflection。

Tool Use

用 @tool 装饰器把普通 Python 函数变成工具,函数的 docstring 就是给 LLM 看的工具说明:

import json, requests
from agentic_patterns.tool_pattern.tool import tool
from agentic_patterns.tool_pattern.tool_agent import ToolAgent

@tool
def fetch_top_hacker_news_stories(top_n: int):
    """Fetch the top stories from Hacker News. 返回 title 与 url 的 JSON。"""
    top_stories_url = 'https://hacker-news.firebaseio.com/v0/topstories.json'
    try:
        response = requests.get(top_stories_url)
        response.raise_for_status()
        top_story_ids = response.json()[:top_n]

        top_stories = []
        for story_id in top_story_ids:
            story_url = f'https://hacker-news.firebaseio.com/v0/item/{story_id}.json'
            story_data = requests.get(story_url).json()
            top_stories.append({
                'title': story_data.get('title', 'No title'),
                'url': story_data.get('url', 'No URL available')
            })

        return json.dumps(top_stories)

    except requests.exceptions.RequestException as e:
        print(f"An error occurred: {e}")
        return []

tool_agent = ToolAgent(tools=[fetch_top_hacker_news_stories])
output = tool_agent.run(user_msg="Tell me the top 5 Hacker News stories right now")
print(output)

参数类型注解决定 LLM 能给工具传什么,返回值统一序列化成 JSON 字符串(这里用 json.dumps)。

这一层的价值是让模型从「说」变成「做」。要注意的边界是:工具的 docstring 和类型注解就是接口契约,写不清楚模型就会传错参数;工具一旦能写数据、发请求、动钱,本身就需要权限约束和幂等设计,别把它当成一个纯函数。只读查询、检索、格式化这类操作适合交给模型决定;有副作用的动作适合让模型提议、由人确认。

Planning

Planning 的典型例子是 ReAct。ReactAgent 是 ToolAgent 的演进版,多了推理与规划能力。给三个算术工具:

@tool
def sum_two_elements(a: int, b: int) -> int:
    return a + b

@tool
def multiply_two_elements(a: int, b: int) -> int:
    return a * b

@tool
def compute_log(x: int) -> float | str:
    if x <= 0:
        return "Logarithm is undefined for values less than or equal to 0."
    return math.log(x)

from agentic_patterns.planning_pattern.react_agent import ReactAgent

agent = ReactAgent(tools=[sum_two_elements, multiply_two_elements, compute_log])

agent.run(user_msg="I want to calculate the sum of 1234 and 5678 and multiply the result by 5. Then, I want to take the logarithm of this result")

即让模型自己决定「调用哪个工具、什么顺序」,而不是写死流程。

它解决的是步骤数事先不确定的任务。代价是每一步都要多一轮模型调用,延迟和成本都比固定流程高;并且在 ReAct 这类循环里,模型可能陷入重复调用或绕圈的行为,需要步数上限。步骤固定、输入格式稳定的流程,写死 pipeline 更快也更便宜,没有理由换成 planning。

Multi-Agent

多智能体部分借用了 CrewAI 的 Agent 与 Crew 两个抽象,并从 Airflow 借了用 >> 运算符定义依赖的思路,把多个 Agent 组成 DAG:

from agentic_patterns.multiagent_pattern.crew import Crew

with Crew() as crew:
    agent_1 = Agent(
        name="Poet Agent",
        backstory="You are a well-known poet...",
        task_description="Write a poem about the meaning of life",
        task_expected_output="Just output the poem...",
    )
    agent_2 = Agent(
        name="Poem Translator Agent",
        backstory="...",
        task_description="Translate a poem into Spanish",
        task_expected_output="Just output the translated poem and nothing else",
    )
    agent_3 = Agent(
        name="Writer Agent",
        backstory="...",
        task_description="Write the poem into './poem.txt'",
        task_expected_output="A txt file...",
        tools=write_str_to_txt,
    )

    agent_1 >> agent_2 >> agent_3

crew.plot()   # 输出 DAG 结构图
crew.run()

每个 Agent 有 name、backstory、task_description、task_expected_output(可带 tools),上游输出进入下游 context。

拆分角色的收益在于每个 Agent 的 prompt 和工具集都能收窄,输出格式也更好约束。边界是:Agent 数量增加,链路里的信息损耗和失败点同步增加,上游一句含糊的输出会被下游放大。如果任务本身只有两三个步骤、角色之间也没有真正的分工,单 Agent 加几个工具就够了。

作者给出的使用路径

README 写得很直接:这是教学项目,不是生产框架。它建议的路径是先看 YouTube 视频,再到 Jupyter Notebook 里改代码、改 prompt,最后(可选)去读 src/ 下的库实现。顺着这条路径走一遍,四个模式各自解决什么、在哪一步开始不好用,会比直接调框架 API 清楚得多。

复制全文 生成海报 andrew ng Agentic AI Agent Reflection ReAct Groq Python

推荐文章

程序员茄子在线接单