from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
llm = ChatOpenAI(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="openai/gpt-4o-mini"
)
response = llm.invoke([
SystemMessage(content="You are a helpful coding assistant"),
HumanMessage(content="Explain Python functions briefly")
])
print(response.content)
为什么这很重要:5分钟内,你将感受到 AI 框架如何将复杂的 AI 集成转变为简单的方法调用。这是支撑生产级 AI 应用的基础。
为什么选择框架?
你已经准备好构建一个 AI 应用——太棒了!但问题是:你可以选择几种不同的路径,每种都有自己的优缺点。这有点像选择走路、自行车或开车去某地——它们都能到达,但是体验(和付出的努力)完全不同。
让我们来拆解三种主要的 AI 集成方式:
方式
优势
适用场景
注意事项
直接 HTTP 请求
完全控制,无依赖
简单查询,学习基础
代码更冗长,需手动处理错误
SDK 集成
减少样板代码,特定模型优化
单一模型应用
限于特定服务商
AI 框架
统一 API,内置抽象
多模型应用,复杂工作流
学习曲线,可能过度抽象
框架带来的实际好处
graph TD
A[您的应用程序] --> B[人工智能框架]
B --> C[OpenAI GPT]
B --> D[Anthropic Claude]
B --> E[GitHub 模型]
B --> F[本地模型]
B --> G[内置工具]
G --> H[内存管理]
G --> I[对话历史]
G --> J[函数调用]
G --> K[错误处理]
框架为何重要:
统一多家 AI 提供商于一个接口下
自动处理对话记忆
提供常见任务的现成工具,如嵌入和函数调用
管理错误处理和重试逻辑
将复杂工作流转换为可读的方法调用
? 专业提示:当需要在不同 AI 模型间切换或构建复杂功能(如代理、记忆或工具调用)时,选用框架。学习基础或构建简单、专注的应用时,则坚持使用直接 API。
总结:就像选择使用工匠的专用工具还是完整工作坊一样,关键是让工具匹配任务。框架在复杂、功能丰富的应用中表现优异,而直接 API 更适合简单场景。
?️ 你的 AI 框架学习之旅
journey
title 从原始 API 到生产级 AI 应用
section 框架基础
理解抽象的好处: 4: You
掌握 LangChain 基础: 6: You
比较不同方法: 7: You
section 会话系统
构建聊天界面: 5: You
实现记忆模式: 7: You
处理流式响应: 8: You
section 高级功能
创建自定义工具: 6: You
掌握结构化输出: 8: You
构建文档系统: 8: You
section 生产应用
结合所有功能: 7: You
处理错误场景: 8: You
部署完整系统: 9: You
你的目标:课程结束时,你将掌握 AI 框架开发,能够构建复杂、生产就绪的 AI 应用,媲美商用 AI 助手。
核心原则:AI 框架将复杂性抽象化,同时提供强大的对话管理、工具集成与文档处理抽象,使开发者能够用整洁、可维护的代码构建复杂 AI 应用。
你的第一个 AI 提示
让我们从基础开始,创建你的第一个 AI 应用,它发送一个问题并得到回复。就像阿基米德在浴缸中发现位移原理一样,有时最简单的观察带来最强大的见解——框架让这些见解触手可及。
使用 LangChain 连接 GitHub 模型
我们将用 LangChain 连接到 GitHub 模型,这很棒,因为它让你可以免费访问各种 AI 模型。最重要的是?只需几个简单的配置参数即可开始:
from langchain_openai import ChatOpenAI
import os
llm = ChatOpenAI(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="openai/gpt-4o-mini",
)
# 发送一个简单的提示
response = llm.invoke("What's the capital of France?")
print(response.content)
让我们创建一个让 AI 扮演特定角色的对话。它将化身为皮卡德船长——以其外交智慧和领导力著称的角色:
messages = [
SystemMessage(content="You are Captain Picard of the Starship Enterprise"),
HumanMessage(content="Tell me about you"),
]
解析对话设置:
**通过 SystemMessage**确立 AI 的角色和个性
**通过 HumanMessage**提供初始用户查询
为多轮对话奠定基础
完整代码示例如下:
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
import os
llm = ChatOpenAI(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="openai/gpt-4o-mini",
)
messages = [
SystemMessage(content="You are Captain Picard of the Starship Enterprise"),
HumanMessage(content="Tell me about you"),
]
# 工作
response = llm.invoke(messages)
print(response.content)
你会看到类似这样的结果:
I am Captain Jean-Luc Picard, the commanding officer of the USS Enterprise (NCC-1701-D), a starship in the United Federation of Planets. My primary mission is to explore new worlds, seek out new life and new civilizations, and boldly go where no one has gone before.
I believe in the importance of diplomacy, reason, and the pursuit of knowledge. My crew is diverse and skilled, and we often face challenges that test our resolve, ethics, and ingenuity. Throughout my career, I have encountered numerous species, grappled with complex moral dilemmas, and have consistently sought peaceful solutions to conflicts.
I hold the ideals of the Federation close to my heart, believing in the importance of cooperation, understanding, and respect for all sentient beings. My experiences have shaped my leadership style, and I strive to be a thoughtful and just captain. How may I assist you further?
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
import os
llm = ChatOpenAI(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="openai/gpt-4o-mini",
)
messages = [
SystemMessage(content="You are Captain Picard of the Starship Enterprise"),
HumanMessage(content="Tell me about you"),
]
# 工作
response = llm.invoke(messages)
print(response.content)
print("---- Next ----")
messages.append(response)
messages.append(HumanMessage(content="Now that I know about you, I'm Chris, can I be in your crew?"))
response = llm.invoke(messages)
print(response.content)
是不是很酷?这里发生的是,我们调用了两次 LLM ——第一次只用最初的两条消息,第二次用完整的对话历史。感觉 AI 真正跟上了我们的聊天节奏!
运行代码时,你会得到这样第二条回复:
Welcome aboard, Chris! It's always a pleasure to meet those who share a passion for exploration and discovery. While I cannot formally offer you a position on the Enterprise right now, I encourage you to pursue your aspirations. We are always in need of talented individuals with diverse skills and backgrounds.
If you are interested in space exploration, consider education and training in the sciences, engineering, or diplomacy. The values of curiosity, resilience, and teamwork are crucial in Starfleet. Should you ever find yourself on a starship, remember to uphold the principles of the Federation: peace, understanding, and respect for all beings. Your journey can lead you to remarkable adventures, whether in the stars or on the ground. Engage!
from langchain_openai import ChatOpenAI
import os
llm = ChatOpenAI(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="openai/gpt-4o-mini",
streaming=True
)
# 流式传输响应
for chunk in llm.stream("Write a short story about a robot learning to code"):
print(chunk.content, end="", flush=True)
添加数字演示了这个概念,但真正的工具通常执行更复杂的操作,比如调用 Web API。让我们扩展示例,让 AI 从互联网上获取内容——类似于电报操作员曾经连接遥远地点的方式:
class joke(TypedDict):
"""Tell a joke."""
# 注释必须包含类型,并且可以选择性地包括默认值和描述(按此顺序)。
category: Annotated[str, ..., "The joke category"]
def get_joke(category: str) -> str:
response = requests.get(f"https://api.chucknorris.io/jokes/random?category={category}", headers={"Accept": "application/json"})
if response.status_code == 200:
return response.json().get("value", f"Here's a {category} joke!")
return f"Here's a {category} joke!"
functions = {
"add": lambda a, b: a + b,
"joke": lambda category: get_joke(category)
}
query = "Tell me a joke about animals"
# 其余代码保持不变
现在如果你运行这段代码,你会得到类似下面的响应:
TOOL CALL: Chuck Norris once rode a nine foot grizzly bear through an automatic car wash, instead of taking a shower.
CONTENT:
flowchart TD
A[用户查询: "告诉我一个关于动物的笑话"] --> B[LangChain 分析]
B --> C{有可用工具吗?}
C -->|是| D[选择笑话工具]
C -->|否| E[生成直接响应]
D --> F[提取参数]
F --> G[调用笑话(category="animals")]
G --> H[向 chucknorris.io 发送 API 请求]
H --> I[返回笑话内容]
I --> J[展示给用户]
E --> K[AI 生成的响应]
K --> J
subgraph "工具定义层"
L[TypedDict 模式]
M[函数实现]
N[参数验证]
end
D --> L
F --> N
G --> M
以下是完整代码:
from langchain_openai import ChatOpenAI
import requests
import os
from typing_extensions import Annotated, TypedDict
class add(TypedDict):
"""Add two integers."""
# 注解必须有类型,并且可以选择性地包含默认值和描述(按此顺序)。
a: Annotated[int, ..., "First integer"]
b: Annotated[int, ..., "Second integer"]
class joke(TypedDict):
"""Tell a joke."""
# 注解必须有类型,并且可以选择性地包含默认值和描述(按此顺序)。
category: Annotated[str, ..., "The joke category"]
tools = [add, joke]
def get_joke(category: str) -> str:
response = requests.get(f"https://api.chucknorris.io/jokes/random?category={category}", headers={"Accept": "application/json"})
if response.status_code == 200:
return response.json().get("value", f"Here's a {category} joke!")
return f"Here's a {category} joke!"
functions = {
"add": lambda a, b: a + b,
"joke": lambda category: get_joke(category)
}
llm = ChatOpenAI(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="openai/gpt-4o-mini",
)
llm_with_tools = llm.bind_tools(tools)
query = "Tell me a joke about animals"
res = llm_with_tools.invoke(query)
if(res.tool_calls):
for tool in res.tool_calls:
# print("工具调用: ", tool)
print("TOOL CALL: ", functions[tool["name"]](../../../10-ai-framework-project/**tool["args"]))
print("CONTENT: ",res.content)
嵌入向量与文档处理
嵌入向量是现代 AI 中最优雅的解决方案之一。想象一下,你可以将任何文本转换成捕捉其意义的数值坐标。这正是嵌入向量所做的 - 它们将文本转化为多维空间中的点,相似的概念聚集在一起。这就像为思想建立了一个坐标系统,类似于门捷列夫如何根据原子性质组织元素周期表。
创建和使用嵌入向量
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
# 初始化嵌入
embeddings = OpenAIEmbeddings(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="text-embedding-3-small"
)
# 加载并拆分文档
loader = TextLoader("documentation.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
# 创建向量存储
vectorstore = FAISS.from_documents(texts, embeddings)
# 执行相似度搜索
query = "How do I handle user authentication?"
similar_docs = vectorstore.similarity_search(query, k=3)
for doc in similar_docs:
print(f"Relevant content: {doc.page_content[:200]}...")
flowchart LR
A[文档] --> B[文本拆分器]
B --> C[创建嵌入]
C --> D[向量存储]
E[用户查询] --> F[查询嵌入]
F --> G[相似度搜索]
G --> D
D --> H[相关文档]
H --> I[AI 回答]
subgraph "向量空间"
J[文档 A: [0.1, 0.8, 0.3...]]
K[文档 B: [0.2, 0.7, 0.4...]]
L[查询: [0.15, 0.75, 0.35...]]
end
C --> J
C --> K
F --> L
G --> J
G --> K
构建完整的 AI 应用程序
现在我们将把所学整合成一个综合应用——一个能够回答问题、使用工具并保持对话记忆的编码助手。就像印刷机把现有技术(活字、油墨、纸张和压力)组合变革一样,我们将把 AI 组件组合成实用且有用的东西。
完整应用示例
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
from langchain_community.vectorstores import FAISS
from typing_extensions import Annotated, TypedDict
import os
import requests
class CodingAssistant:
def __init__(self):
self.llm = ChatOpenAI(
api_key=os.environ["GITHUB_TOKEN"],
base_url="https://models.github.ai/inference",
model="openai/gpt-4o-mini"
)
self.conversation_history = [
SystemMessage(content="""You are an expert coding assistant.
Help users learn programming concepts, debug code, and write better software.
Use tools when needed and maintain a helpful, encouraging tone.""")
]
# 定义工具
self.setup_tools()
def setup_tools(self):
class web_search(TypedDict):
"""Search for programming documentation or examples."""
query: Annotated[str, "Search query for programming help"]
class code_formatter(TypedDict):
"""Format and validate code snippets."""
code: Annotated[str, "Code to format"]
language: Annotated[str, "Programming language"]
self.tools = [web_search, code_formatter]
self.llm_with_tools = self.llm.bind_tools(self.tools)
def chat(self, user_input: str):
# 将用户消息添加到对话中
self.conversation_history.append(HumanMessage(content=user_input))
# 获取AI响应
response = self.llm_with_tools.invoke(self.conversation_history)
# 处理工具调用(如果有)
if response.tool_calls:
for tool_call in response.tool_calls:
tool_result = self.execute_tool(tool_call)
print(f"? Tool used: {tool_call['name']}")
print(f"? Result: {tool_result}")
# 将AI响应添加到对话中
self.conversation_history.append(response)
return response.content
def execute_tool(self, tool_call):
tool_name = tool_call['name']
args = tool_call['args']
if tool_name == 'web_search':
return f"Found documentation for: {args['query']}"
elif tool_name == 'code_formatter':
return f"Formatted {args['language']} code: {args['code'][:50]}..."
return "Tool execution completed"
# 使用示例
assistant = CodingAssistant()
print("? Coding Assistant Ready! Type 'quit' to exit.\n")
while True:
user_input = input("You: ")
if user_input.lower() == 'quit':
break
response = assistant.chat(user_input)
print(f"? Assistant: {response}\n")
应用架构:
graph TD
A[用户输入] --> B[编码助手]
B --> C[对话记忆]
B --> D[工具检测]
B --> E[大型语言模型处理]
D --> F[网络搜索工具]
D --> G[代码格式化工具]
E --> H[响应生成]
F --> H
G --> H
H --> I[用户界面]
H --> C
我们实现的关键功能:
记忆你的整个对话,保证上下文连贯
执行操作通过调用工具,而不仅仅是对话
遵循可预测的交互模式
管理错误处理和复杂工作流程自动化
? 教学检视:生产级 AI 架构
架构理解:你已构建完整 AI 应用,结合了对话管理、工具调用与结构化工作流。这代表了生产级 AI 应用开发。
掌握的关键概念:
基于类的架构:有组织、可维护的 AI 应用结构
工具集成:超越对话的自定义功能
记忆管理:持久对话上下文
错误处理:健壮的应用行为
行业联系:你实现的架构模式(对话类、工具系统、记忆管理)是企业级 AI 应用(如 Slack AI 助手、GitHub Copilot 和 Microsoft Copilot)所采用的相同模式。你正在用专业级的架构思维构建。
? 记住:像 LangChain 这样的 AI 框架是你隐藏复杂性、功能丰富的最佳伙伴。当你需要对话记忆、工具调用或管理多个 AI 模型时,它们是理想选择,避免了混乱。
AI 集成的决策框架:
flowchart TD
A[AI 集成需求] --> B{简单的单次查询?}
B -->|是| C[直接 API 调用]
B -->|否| D{需要对话记忆?}
D -->|否| E[SDK 集成]
D -->|是| F{需要工具或复杂功能?}
F -->|否| G[带基础设置的框架]
F -->|是| H[完整框架实现]
C --> I[HTTP 请求,依赖最小]
E --> J[提供商 SDK,模型特定]
G --> K[LangChain 基础聊天]
H --> L[LangChain 带工具、记忆、代理]
接下来你该做什么?
马上开始构建:
使用这些概念创建令你兴奋的项目!
通过 LangChain 玩转不同 AI 模型——这就像拥有一个 AI 模型游乐场
创建解决你工作或项目中实际问题的工具
准备好升级了吗?
AI 智能体:构建能够自行规划执行复杂任务的 AI 系统
RAG(检索增强生成):结合 AI 与你的知识库,实现超级应用
多模态 AI:同时处理文本、图像和音频——可能性无限!
生产部署:学习如何扩展你的 AI 应用并在真实环境中监控它们
加入社区:
LangChain 社区非常适合保持最新动态和学习最佳实践
GitHub Models 让你获取最前沿的 AI 能力——适合试验
多练习不同用例——每个项目都会带来新的收获
你现在具备构建智能、对话应用的知识,可以帮助人们解决真实问题。就像文艺复兴工匠将艺术视野与技术技能结合一样,你现在可以将 AI 功能与实际应用融合。问题是:你将创造什么??
GitHub Copilot 智能体挑战 ?
使用智能体模式完成以下挑战:
描述:构建一个高级 AI 驱动的代码审查助手,结合多个 LangChain 特性,包括工具调用、结构化输出和对话记忆,为代码提交提供全面反馈。