一文帶你讀懂 Google LangGraph 項目,快速入門 AI Agent 全棧開發
一、項目背景與目標
最近在帶着同事一起做智能 Agent 相關的內部項目,發現很多人對 LangGraph 非常感興趣,但又不太清楚如何從零開始搭建一個完整的 AI Agent,我於是在 github 上找,看看有沒有好的開源項目給他們學習,偶然間發現了 google-gemini 開源的這個項目 [1],正好拿來給他們講講,學習學習。發現整理的材料又正好可以出一期公衆號文章,就作爲我公衆號的一篇番外,來講講。
題外話:我十分不主張,一遇到新需求,就好像對應的知識就得全部掌握,得去花大力氣看看基礎教程,瞭解全貌之後,再開始行動。如果真是這樣的話,這個項目大概率就得黃了。應該是要根據目標去找,去按需學習。
你可能已經用過市面上的一些 “低代碼 / 零代碼” 智能體平臺,比如 Coze、Dify 這類產品。它們就像搭積木一樣,讓你拖拽組件、配置流程,快速拼出一個屬於自己的 AI Agent。這種方式對於業務快速上線、簡單場景非常友好。
但你有沒有遇到過這樣的問題:
-
• 想要更深度的自定義,發現平臺的 “積木” 不夠用?
-
• 想搞懂 Agent 內部到底是怎麼一步步推理、搜索、反思、合成答案的?
-
• 希望做私有化部署、對接企業內網、或者實現一些平臺不支持的高級功能?
這時候,你就需要跳出 “應用端拼裝”,進入 “代碼層級的自定義”。本項目就是爲此而生——它不僅讓你看到一個完整的 “AI 研究員” 是怎麼從零到一搭建起來的,還能讓你隨時插拔、擴展、魔改每一個環節。
它適合:
-
• 希望瞭解 LangGraph 實踐的開發者
-
• 想要構建帶有 “智能搜索 + 推理 + 引用” 功能的對話 / 問答系統的團隊
-
• 需要端到端範例、可直接二次開發的工程師
核心亮點:
-
• 通過 LangGraph 低代碼方式編排 “生成 - 搜索 - 反思 - 合成”AI 代理流程
-
• 支持 Google Search API 實時查找資料,答案帶引用
-
• 前端 React + Vite,後端 Python + FastAPI + LangGraph
在接下來的內容中,我會像一位帶你實戰的講師,帶你從全局到細節,逐步拆解這個項目的每一處關鍵實現。
二、項目組成與架構
在正式讀代碼前,我們先快速瞭解一下項目的整體結構和技術選型。
目錄結構簡述:
-
•
frontend/:React 前端,負責 UI 展示、與後端 API 通信 -
•
backend/:Python 後端,核心爲 LangGraph 代理 -
•
src/agent/:代理主流程、工具、狀態定義 -
•
examples/cli_research.py:命令行調用代理的最小示例
技術棧:
-
• 前端:React、Vite、Tailwind CSS
-
• 後端:Python 3.11+、LangGraph、Google Gemini、FastAPI
核心流程:
-
- 用戶輸入問題(網頁或命令行)
-
- 代理自動生成搜索詞 → Google 搜索 → Gemini 總結 → 反思知識盲區 → 迭代補充 → 合成帶引用的答案
你可以把它想象成一個 “AI 研究員”,自動幫你查資料、歸納、補充、引用,最後給你一份有理有據的答案。
三、如何啓動和體驗項目
在動手讀代碼前,我們先來體驗一下項目的實際效果。
1. 環境準備
-
• Node.js 16+、npm
-
• Python 3.11+
-
• Google Gemini API Key(必需)
2. 安裝依賴
在項目根目錄下:
setup.bat install
或分別:
setup.bat install-backend
setup.bat install-frontend
3. 運行開發環境
setup.bat dev
-
• 會自動彈出前端和後端窗口,前端訪問 http://localhost:5173/app
-
• 關閉服務只需關閉彈出的命令行窗口
4. 命令行體驗
setup.bat cli-example "今天武漢的天氣怎麼樣?"
- • 直接在終端輸出帶引用的答案
你可以先隨便問一個問題,感受一下 “processing...” 之後,AI 是如何給你一份帶引用的研究報告的。
四、端到端代碼導讀
接下來,讓我們像課堂實戰一樣,帶着問題、帶着好奇心,一步步走進項目的核心實現。
1. 入口:命令行調用
我們先從最簡單的命令行入口開始。
文件:backend/examples/cli_research.py
-
• 入口:
if __name__ == "__main__": main()(第 42 行) -
• 主函數:
main()(第 5 行)
你可以打開這個文件,看到如下關鍵代碼:
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
-
• graph 定義:
graph = builder.compile()(第 293 行) -
• StateGraph 構建:第 269 行起
你會看到一段類似 “流程圖” 的代碼:
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行
林生點評:
-
• 這就是 LangGraph 的 “流程編排” 能力。每個節點(Node)就是一個處理環節,節點之間的連線(Edge)決定了流程怎麼走、是否循環。
-
• 你可以把它想象成 “AI 研究員的工作流”:先生成搜索詞,再查資料,再反思,再查補充,最後合成答案。
3. 節點實現詳解
現在我們帶着 “AI 研究員” 的視角,逐個節點來看它們都做了什麼。
3.1. generate_query 節點
-
• 定義:
def generate_query(state: OverallState, config: RunnableConfig) -> QueryGenerationState:(第 44 行) -
• 作用:用 Gemini LLM 生成適合搜索的關鍵詞。
-
• 關注點:prompt 構造、LLM 調用、輸出結構。
-
• 關鍵代碼:
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}
- • 林生提示:這裏的
SearchQueryList是在 tools_and_schemas.py 裏定義的結構,專門用來描述 “搜索詞列表 + 理由”。
3.2. continue_to_web_research 節點
-
• 定義:
def continue_to_web_research(state: QueryGenerationState):(第 84 行) -
• 作用:把每個搜索詞分發到 web_research 節點。
-
• 關鍵代碼:
return [
Send("web_research", {"search_query": search_query, "id": int(idx)})
for idx, search_query in enumerate(state["search_query"])
]
- • 林生提示:這裏用到了 LangGraph 的 “並行分發” 能力,每個搜索詞都可以獨立查資料。
3.3. web_research 節點
-
• 定義:
def web_research(state: WebSearchState, config: RunnableConfig) -> OverallState:(第 95 行) -
• 作用:用 Google Search API + Gemini LLM 查找並總結網頁內容。
-
• 關注點:API 調用、引用提取、結果格式。
-
• 關鍵代碼:
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],
}
- • 林生提示:這裏的 “查資料” 其實是 Gemini LLM 通過 Google Search 工具能力,自動抓取網頁、提取引用、生成帶引用的總結。
3.4. reflection 節點
-
• 定義:
def reflection(state: OverallState, config: RunnableConfig) -> ReflectionState:(第 139 行) -
• 作用:用 Gemini LLM 反思當前資料是否足夠,生成補充查詢詞。
-
• 關鍵代碼:
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,
...
}
- • 林生提示:這裏的
Reflection結構體也是在 tools_and_schemas.py 裏定義的,描述 “是否足夠、知識盲區、補充查詢”。
3.5. evaluate_research 節點
-
• 定義:
def evaluate_research(state: ReflectionState, config: RunnableConfig) -> OverallState:(第 183 行) -
• 作用:判斷是否繼續 web_research 還是進入 finalize_answer。
-
• 關鍵代碼:
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"])
]
- • 林生提示:這裏就是 “AI 研究員” 決定要不要繼續查補充資料的地方。
3.6. finalize_answer 節點
-
• 定義:
def finalize_answer(state: OverallState, config: RunnableConfig):(第 220 行) -
• 作用:用 Gemini LLM 合成最終答案,整理引用。
-
• 關鍵代碼:
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. 數據結構與工具定義
在讀節點實現時,你可能會好奇:SearchQueryList、Reflection 這些結構體是怎麼定義的?
文件:backend/src/agent/tools_and_schemas.py
-
•
SearchQueryList(第 5 行):定義了搜索詞列表和 rationale。 -
•
Reflection(第 14 行):定義了反思節點的輸出結構。
你可以隨時跳到這個文件,看看每個字段的含義和註釋。
5. 總結跳轉鏈路
到這裏,我們已經帶着 “AI 研究員” 的視角,完整走了一遍從命令行輸入到最終答案輸出的全鏈路。
-
1. 入口:
cli_research.py第 36 行graph.invoke(state) -
2. 流程定義:
graph.py第 269-291 行(StateGraph 構建) -
3. 節點實現:
graph.py第 36-265 行(每個節點的具體邏輯) -
4. 數據結構:
tools_and_schemas.py(第 5-24 行)
你可以跟着這些跳轉,邊看邊實驗,體會每一步的數據流轉和設計巧思。
6. 建議的學習方式
最後,給大家一些實戰建議:
-
• 跟着每個 “文件 + 行號 + 關注點” 定位代碼,邊看邊在本地加 print/log,體會數據流轉。
-
• 遇到不懂的類型(如
SearchQueryList、Reflection),可跳到tools_and_schemas.py查看定義。 -
• 如果想看 “Google Search API” 具體怎麼調用的,可進一步跳到
tools_and_schemas.py或utils.py。 -
• 多用命令行和前端實際提問,結合日誌和代碼理解每一步。
本文章可作爲寫作、講解、二次開發的基礎材料,歡迎補充和完善!希望你能像帶着學員實戰一樣,真正掌握 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