一文帶你讀懂 Google LangGraph 項目,快速入門 AI Agent 全棧開發

一、項目背景與目標

最近在帶着同事一起做智能 Agent 相關的內部項目,發現很多人對 LangGraph 非常感興趣,但又不太清楚如何從零開始搭建一個完整的 AI Agent,我於是在 github 上找,看看有沒有好的開源項目給他們學習,偶然間發現了 google-gemini 開源的這個項目 [1],正好拿來給他們講講,學習學習。發現整理的材料又正好可以出一期公衆號文章,就作爲我公衆號的一篇番外,來講講。

題外話:我十分不主張,一遇到新需求,就好像對應的知識就得全部掌握,得去花大力氣看看基礎教程,瞭解全貌之後,再開始行動。如果真是這樣的話,這個項目大概率就得黃了。應該是要根據目標去找,去按需學習。

你可能已經用過市面上的一些 “低代碼 / 零代碼” 智能體平臺,比如 Coze、Dify 這類產品。它們就像搭積木一樣,讓你拖拽組件、配置流程,快速拼出一個屬於自己的 AI Agent。這種方式對於業務快速上線、簡單場景非常友好。

但你有沒有遇到過這樣的問題:

這時候,你就需要跳出 “應用端拼裝”,進入 “代碼層級的自定義”。本項目就是爲此而生——它不僅讓你看到一個完整的 “AI 研究員” 是怎麼從零到一搭建起來的,還能讓你隨時插拔、擴展、魔改每一個環節。

它適合:

核心亮點

在接下來的內容中,我會像一位帶你實戰的講師,帶你從全局到細節,逐步拆解這個項目的每一處關鍵實現。

二、項目組成與架構

在正式讀代碼前,我們先快速瞭解一下項目的整體結構和技術選型。

目錄結構簡述

技術棧

核心流程

    1. 用戶輸入問題(網頁或命令行)
    1. 代理自動生成搜索詞 → Google 搜索 → Gemini 總結 → 反思知識盲區 → 迭代補充 → 合成帶引用的答案

你可以把它想象成一個 “AI 研究員”,自動幫你查資料、歸納、補充、引用,最後給你一份有理有據的答案。

三、如何啓動和體驗項目

在動手讀代碼前,我們先來體驗一下項目的實際效果。

1. 環境準備

2. 安裝依賴

在項目根目錄下:

setup.bat install

或分別:

setup.bat install-backend
setup.bat install-frontend

3. 運行開發環境

setup.bat dev

4. 命令行體驗

setup.bat cli-example "今天武漢的天氣怎麼樣?"

你可以先隨便問一個問題,感受一下 “processing...” 之後,AI 是如何給你一份帶引用的研究報告的。

四、端到端代碼導讀

接下來,讓我們像課堂實戰一樣,帶着問題、帶着好奇心,一步步走進項目的核心實現。

1. 入口:命令行調用

我們先從最簡單的命令行入口開始。

文件backend/examples/cli_research.py

你可以打開這個文件,看到如下關鍵代碼:

from agent.graph import graph  # 第3行
...
result = graph.invoke(state)   # 第36行

這裏的 graph.invoke(state),就是整個 “AI 研究員” 流程的起點。你輸入一個問題,所有的自動研究、搜索、推理、引用,都是從這裏開始的。

小貼士:如果你想快速體驗後端的效果,可以直接在命令行運行:

python backend/examples/cli_research.py "今天武漢的天氣怎麼樣?"

2. 跳轉到核心代理定義

接下來,我們順着 from agent.graph import graph 跳到核心代理的定義。

文件backend/src/agent/graph.py

你會看到一段類似 “流程圖” 的代碼:

builder.add_node("generate_query", generate_query)      # 第272行
builder.add_node("web_research", web_research)          # 第273行
builder.add_node("reflection", reflection)              # 第274行
builder.add_node("finalize_answer", finalize_answer)    # 第275行
...
builder.add_edge(START, "generate_query")               # 第279行
builder.add_conditional_edges("generate_query", continue_to_web_research, ["web_research"]) # 第281行
builder.add_edge("web_research""reflection")          # 第285行
builder.add_conditional_edges("reflection", evaluate_research, ["web_research""finalize_answer"]) # 第287行
builder.add_edge("finalize_answer", END)                # 第291行

林生點評

3. 節點實現詳解

現在我們帶着 “AI 研究員” 的視角,逐個節點來看它們都做了什麼。

3.1. generate_query 節點

llm = ChatGoogleGenerativeAI(...)
structured_llm = llm.with_structured_output(SearchQueryList)
formatted_prompt = query_writer_instructions.format(...)
result = structured_llm.invoke(formatted_prompt)
return {"search_query": result.query}

3.2. continue_to_web_research 節點

return [
    Send("web_research", {"search_query": search_query, "id": int(idx)})
    for idx, search_query in enumerate(state["search_query"])
]

3.3. web_research 節點

response = genai_client.models.generate_content(...)
resolved_urls = resolve_urls(...)
citations = get_citations(response, resolved_urls)
modified_text = insert_citation_markers(response.text, citations)
sources_gathered = [item for citation in citations for item in citation["segments"]]
return {
    "sources_gathered": sources_gathered,
    "search_query": [state["search_query"]],
    "web_research_result": [modified_text],
}

3.4. reflection 節點

formatted_prompt = reflection_instructions.format(...)
llm = ChatGoogleGenerativeAI(...)
result = llm.with_structured_output(Reflection).invoke(formatted_prompt)
return {
    "is_sufficient": result.is_sufficient,
    "knowledge_gap": result.knowledge_gap,
    "follow_up_queries": result.follow_up_queries,
    ...
}

3.5. evaluate_research 節點

if state["is_sufficient"] or state["research_loop_count"] >= max_research_loops:
    return "finalize_answer"
else:
    return [
        Send("web_research", {...})
        for idx, follow_up_query in enumerate(state["follow_up_queries"])
    ]

3.6. finalize_answer 節點

formatted_prompt = answer_instructions.format(...)
llm = ChatGoogleGenerativeAI(...)
result = llm.invoke(formatted_prompt)
# 替換短鏈爲原始鏈接
for source in state["sources_gathered"]:
    if source["short_url"] in result.content:
        result.content = result.content.replace(
            source["short_url"], source["value"]
        )
        unique_sources.append(source)
return {
    "messages": [AIMessage(content=result.content)],
    "sources_gathered": unique_sources,
}

4. 數據結構與工具定義

在讀節點實現時,你可能會好奇:SearchQueryListReflection 這些結構體是怎麼定義的?

文件backend/src/agent/tools_and_schemas.py

你可以隨時跳到這個文件,看看每個字段的含義和註釋。

5. 總結跳轉鏈路

到這裏,我們已經帶着 “AI 研究員” 的視角,完整走了一遍從命令行輸入到最終答案輸出的全鏈路。

  1. 1. 入口cli_research.py 第 36 行 graph.invoke(state)

  2. 2. 流程定義graph.py 第 269-291 行(StateGraph 構建)

  3. 3. 節點實現graph.py 第 36-265 行(每個節點的具體邏輯)

  4. 4. 數據結構tools_and_schemas.py(第 5-24 行)

你可以跟着這些跳轉,邊看邊實驗,體會每一步的數據流轉和設計巧思。

6. 建議的學習方式

最後,給大家一些實戰建議:


本文章可作爲寫作、講解、二次開發的基礎材料,歡迎補充和完善!希望你能像帶着學員實戰一樣,真正掌握 LangGraph 應用開發的精髓。

原先的 google-gemini 該項目的地址如下,大家可以跳轉去看:https://github.com/google-gemini/gemini-fullstack-langgraph-quickstart

我在這個項目的基礎上進行了部分修改,有完整的中文使用教程,以及本地 Windows 部署腳本調整,方便大家直接運行和二次開發。如果對這塊感興趣,可以關注我的微信公衆號,直接發消息 “langgraph”, 即可獲得該項目的完整代碼和使用教程。

如果你對 AI 落地企業應用的話題感興趣,歡迎關注我的公衆號,獲取更多實戰內容和項目更新。

我是林生,我們下期再見!

引用鏈接

[1] 項目: https://github.com/google-gemini/gemini-fullstack-langgraph-quickstart

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/BtMtzyUzfYF2-gdFfq07mQ