agents-towards-production
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAgents Towards Production
面向生产环境的Agent开发
Skill by ara.so — AI Agent Skills collection.
This skill enables you to build production-grade GenAI agents from prototype to enterprise deployment. The repository provides 28+ end-to-end tutorials covering stateful workflows, vector memory, real-time web search, Docker deployment, FastAPI endpoints, security guardrails, GPU scaling, browser automation, multi-agent coordination, observability, evaluation, and UI development.
由ara.so提供的技能——AI Agent技能合集。
本技能可帮助你从原型构建到企业级部署,打造生产级GenAI Agent。该仓库提供了28+个端到端教程,涵盖有状态工作流、向量存储、实时网页搜索、Docker部署、FastAPI接口、安全防护、GPU扩容、浏览器自动化、多Agent协同、可观测性、评估以及UI开发等内容。
What It Does
功能介绍
Agents Towards Production is a comprehensive tutorial collection for building real-world AI agents that scale. It covers:
- Agent Frameworks: LangGraph, LangChain for stateful workflows and orchestration
- Memory Systems: Vector storage with Redis, Mem0 for persistent agent memory
- RAG Integration: Retrieval-augmented generation with Contextual AI
- Web Access: Real-time search APIs (Tavily), web scraping (Bright Data)
- Deployment: Docker, FastAPI, GPU scaling, production infrastructure
- Security: Guardrails, OAuth2, human-in-the-loop controls (Arcade)
- Multi-Agent: Coordination, orchestration, distributed workflows
- Observability: Monitoring, evaluation, debugging production agents
- UI Development: Browser automation, user interfaces
《面向生产环境的Agent开发》是一套全面的教程合集,用于构建可扩展的真实世界AI Agent。内容涵盖:
- Agent框架:使用LangGraph、LangChain实现有状态工作流与编排
- 存储系统:基于Redis、Mem0的向量存储,实现Agent持久化存储
- RAG集成:结合Contextual AI实现检索增强生成
- 网页访问:实时搜索API(Tavily)、网页抓取(Bright Data)
- 部署方案:Docker、FastAPI、GPU扩容、生产级基础设施
- 安全防护:防护机制、OAuth2、人工介入控制(Arcade)
- 多Agent协同:Agent协调、编排、分布式工作流
- 可观测性:生产环境Agent的监控、评估与调试
- UI开发:浏览器自动化、用户界面
Installation
安装步骤
Clone the repository:
bash
git clone https://github.com/NirDiamant/agents-towards-production.git
cd agents-towards-productionInstall dependencies (each tutorial has its own requirements):
bash
undefined克隆仓库:
bash
git clone https://github.com/NirDiamant/agents-towards-production.git
cd agents-towards-production安装依赖(每个教程有独立的依赖要求):
bash
undefinedFor LangGraph tutorials
适用于LangGraph教程
pip install langchain langgraph langchain-openai langchain-community
pip install langchain langgraph langchain-openai langchain-community
For memory tutorials
适用于存储教程
pip install redis langchain-redis mem0ai
pip install redis langchain-redis mem0ai
For RAG tutorials
适用于RAG教程
pip install contextual-client chromadb sentence-transformers
pip install contextual-client chromadb sentence-transformers
For web access
适用于网页访问
pip install tavily-python brightdata-sdk
pip install tavily-python brightdata-sdk
For deployment
适用于部署
pip install fastapi uvicorn docker pydantic
pip install fastapi uvicorn docker pydantic
For observability
适用于可观测性
pip install langsmith weave opentelemetry
undefinedpip install langsmith weave opentelemetry
undefinedKey Tutorials and Usage Patterns
核心教程与使用模式
1. Basic LangGraph Agent
1. 基础LangGraph Agent
Create a stateful agent with LangGraph:
python
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
import os使用LangGraph创建有状态Agent:
python
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
import osDefine state
定义状态
class AgentState(TypedDict):
messages: List[dict]
current_step: str
class AgentState(TypedDict):
messages: List[dict]
current_step: str
Initialize LLM
初始化LLM
llm = ChatOpenAI(
model="gpt-4",
api_key=os.getenv("OPENAI_API_KEY")
)
llm = ChatOpenAI(
model="gpt-4",
api_key=os.getenv("OPENAI_API_KEY")
)
Define agent nodes
定义Agent节点
def process_input(state: AgentState):
"""Process user input"""
messages = state["messages"]
response = llm.invoke(messages)
return {
"messages": messages + [{"role": "assistant", "content": response.content}],
"current_step": "completed"
}
def process_input(state: AgentState):
"""处理用户输入"""
messages = state["messages"]
response = llm.invoke(messages)
return {
"messages": messages + [{"role": "assistant", "content": response.content}],
"current_step": "completed"
}
Build graph
构建图
workflow = StateGraph(AgentState)
workflow.add_node("process", process_input)
workflow.set_entry_point("process")
workflow.add_edge("process", END)
workflow = StateGraph(AgentState)
workflow.add_node("process", process_input)
workflow.set_entry_point("process")
workflow.add_edge("process", END)
Compile and run
编译并运行
app = workflow.compile()
result = app.invoke({
"messages": [{"role": "user", "content": "Hello, how can you help me?"}],
"current_step": "start"
})
print(result["messages"][-1]["content"])
undefinedapp = workflow.compile()
result = app.invoke({
"messages": [{"role": "user", "content": "Hello, how can you help me?"}],
"current_step": "start"
})
print(result["messages"][-1]["content"])
undefined2. Agent with Vector Memory (Redis)
2. 集成Redis向量存储的Agent
Add persistent memory to your agent:
python
from langchain_redis import RedisVectorStore, RedisConfig
from langchain_openai import OpenAIEmbeddings
from langchain.schema import Document
import os为Agent添加持久化存储:
python
from langchain_redis import RedisVectorStore, RedisConfig
from langchain_openai import OpenAIEmbeddings
from langchain.schema import Document
import osConfigure Redis
配置Redis
redis_config = RedisConfig(
index_name="agent_memory",
redis_url=os.getenv("REDIS_URL", "redis://localhost:6379"),
distance_metric="COSINE"
)
redis_config = RedisConfig(
index_name="agent_memory",
redis_url=os.getenv("REDIS_URL", "redis://localhost:6379"),
distance_metric="COSINE"
)
Initialize vector store
初始化向量存储
embeddings = OpenAIEmbeddings(api_key=os.getenv("OPENAI_API_KEY"))
vector_store = RedisVectorStore(
config=redis_config,
embedding=embeddings
)
embeddings = OpenAIEmbeddings(api_key=os.getenv("OPENAI_API_KEY"))
vector_store = RedisVectorStore(
config=redis_config,
embedding=embeddings
)
Store conversation memory
存储对话记录
def store_memory(user_id: str, conversation: str, metadata: dict = None):
"""Store conversation in vector memory"""
doc = Document(
page_content=conversation,
metadata={"user_id": user_id, **(metadata or {})}
)
vector_store.add_documents([doc])
def store_memory(user_id: str, conversation: str, metadata: dict = None):
"""将对话存储到向量存储中"""
doc = Document(
page_content=conversation,
metadata={"user_id": user_id, **(metadata or {})}
)
vector_store.add_documents([doc])
Retrieve relevant memories
检索相关记录
def retrieve_memory(user_id: str, query: str, k: int = 3):
"""Retrieve relevant past conversations"""
results = vector_store.similarity_search(
query,
k=k,
filter={"user_id": user_id}
)
return [doc.page_content for doc in results]
def retrieve_memory(user_id: str, query: str, k: int = 3):
"""检索相关的历史对话"""
results = vector_store.similarity_search(
query,
k=k,
filter={"user_id": user_id}
)
return [doc.page_content for doc in results]
Usage
使用示例
store_memory(
user_id="user123",
conversation="User asked about Python tutorials. Agent provided resources.",
metadata={"topic": "python", "timestamp": "2024-01-15"}
)
memories = retrieve_memory("user123", "What did we discuss about programming?")
print("Relevant memories:", memories)
undefinedstore_memory(
user_id="user123",
conversation="User asked about Python tutorials. Agent provided resources.",
metadata={"topic": "python", "timestamp": "2024-01-15"}
)
memories = retrieve_memory("user123", "What did we discuss about programming?")
print("Relevant memories:", memories)
undefined3. RAG Agent with Contextual AI
3. 集成Contextual AI的RAG Agent
Build a retrieval-augmented generation agent:
python
from contextual_client import ContextualClient
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
import os构建检索增强生成Agent:
python
from contextual_client import ContextualClient
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
import osInitialize Contextual client
初始化Contextual客户端
contextual = ContextualClient(api_key=os.getenv("CONTEXTUAL_API_KEY"))
contextual = ContextualClient(api_key=os.getenv("CONTEXTUAL_API_KEY"))
Create knowledge base
创建知识库
kb = contextual.create_knowledge_base(
name="product_docs",
description="Product documentation and FAQs"
)
kb = contextual.create_knowledge_base(
name="product_docs",
description="Product documentation and FAQs"
)
Index documents
索引文档
documents = [
{"content": "Our API supports REST and GraphQL endpoints.", "metadata": {"type": "api"}},
{"content": "Authentication uses OAuth2 with JWT tokens.", "metadata": {"type": "auth"}},
]
contextual.index_documents(knowledge_base_id=kb.id, documents=documents)
documents = [
{"content": "Our API supports REST and GraphQL endpoints.", "metadata": {"type": "api"}},
{"content": "Authentication uses OAuth2 with JWT tokens.", "metadata": {"type": "auth"}},
]
contextual.index_documents(knowledge_base_id=kb.id, documents=documents)
RAG query function
RAG查询函数
def rag_query(question: str):
"""Query with retrieval-augmented generation"""
# Retrieve relevant context
results = contextual.search(
knowledge_base_id=kb.id,
query=question,
top_k=3
)
context = "\n".join([r.content for r in results])
# Generate response with context
prompt = ChatPromptTemplate.from_template("""
Answer the question based on the following context:
Context: {context}
Question: {question}
Answer:
""")
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
chain = prompt | llm
response = chain.invoke({"context": context, "question": question})
return response.contentdef rag_query(question: str):
"""基于检索增强生成的查询"""
# 检索相关上下文
results = contextual.search(
knowledge_base_id=kb.id,
query=question,
top_k=3
)
context = "\n".join([r.content for r in results])
# 结合上下文生成响应
prompt = ChatPromptTemplate.from_template("""
根据以下上下文回答问题:
上下文:{context}
问题:{question}
回答:
""")
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
chain = prompt | llm
response = chain.invoke({"context": context, "question": question})
return response.contentUsage
使用示例
answer = rag_query("How does authentication work?")
print(answer)
undefinedanswer = rag_query("How does authentication work?")
print(answer)
undefined4. Web Search Agent with Tavily
4. 集成Tavily的网页搜索Agent
Add real-time web search capabilities:
python
from tavily import TavilyClient
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
import os添加实时网页搜索能力:
python
from tavily import TavilyClient
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
import osInitialize Tavily
初始化Tavily
tavily = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
def web_search_agent(query: str):
"""Agent with real-time web search"""
# Search the web
search_results = tavily.search(
query=query,
search_depth="advanced",
max_results=5,
include_domains=None,
exclude_domains=None
)
# Format results
context = "\n\n".join([
f"Source: {r['url']}\n{r['content']}"
for r in search_results.get('results', [])
])
# Generate response
prompt = ChatPromptTemplate.from_template("""
Based on the following web search results, answer the user's question:
Search Results:
{context}
Question: {question}
Provide a comprehensive answer with sources:
""")
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
chain = prompt | llm
response = chain.invoke({"context": context, "question": query})
return {
"answer": response.content,
"sources": [r['url'] for r in search_results.get('results', [])]
}tavily = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
def web_search_agent(query: str):
"""具备实时网页搜索能力的Agent"""
# 网页搜索
search_results = tavily.search(
query=query,
search_depth="advanced",
max_results=5,
include_domains=None,
exclude_domains=None
)
# 格式化结果
context = "\n\n".join([
f"Source: {r['url']}\n{r['content']}"
for r in search_results.get('results', [])
])
# 生成响应
prompt = ChatPromptTemplate.from_template("""
根据以下网页搜索结果,回答用户的问题:
搜索结果:
{context}
问题:{question}
提供包含来源的全面回答:
""")
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
chain = prompt | llm
response = chain.invoke({"context": context, "question": query})
return {
"answer": response.content,
"sources": [r['url'] for r in search_results.get('results', [])]
}Usage
使用示例
result = web_search_agent("What are the latest developments in AI agents?")
print(result["answer"])
print("\nSources:", result["sources"])
undefinedresult = web_search_agent("What are the latest developments in AI agents?")
print(result["answer"])
print("\nSources:", result["sources"])
undefined5. Multi-Agent Coordination
5. 多Agent协同
Coordinate multiple specialized agents:
python
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from typing import TypedDict, List, Literal
import os
class MultiAgentState(TypedDict):
messages: List[dict]
task: str
current_agent: str
results: dict协调多个专业Agent:
python
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from typing import TypedDict, List, Literal
import os
class MultiAgentState(TypedDict):
messages: List[dict]
task: str
current_agent: str
results: dictDefine specialized agents
定义专业Agent
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
def research_agent(state: MultiAgentState):
"""Research specialist"""
prompt = f"Research the following: {state['task']}"
response = llm.invoke([{"role": "user", "content": prompt}])
state["results"]["research"] = response.content
return state
def analysis_agent(state: MultiAgentState):
"""Analysis specialist"""
research = state["results"].get("research", "")
prompt = f"Analyze this research:\n{research}"
response = llm.invoke([{"role": "user", "content": prompt}])
state["results"]["analysis"] = response.content
return state
def synthesis_agent(state: MultiAgentState):
"""Synthesis specialist"""
analysis = state["results"].get("analysis", "")
prompt = f"Synthesize findings:\n{analysis}"
response = llm.invoke([{"role": "user", "content": prompt}])
state["results"]["synthesis"] = response.content
return state
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
def research_agent(state: MultiAgentState):
"""研究专家Agent"""
prompt = f"Research the following: {state['task']}"
response = llm.invoke([{"role": "user", "content": prompt}])
state["results"]["research"] = response.content
return state
def analysis_agent(state: MultiAgentState):
"""分析专家Agent"""
research = state["results"].get("research", "")
prompt = f"Analyze this research:\n{research}"
response = llm.invoke([{"role": "user", "content": prompt}])
state["results"]["analysis"] = response.content
return state
def synthesis_agent(state: MultiAgentState):
"""综合专家Agent"""
analysis = state["results"].get("analysis", "")
prompt = f"Synthesize findings:\n{analysis}"
response = llm.invoke([{"role": "user", "content": prompt}])
state["results"]["synthesis"] = response.content
return state
Router function
路由函数
def route_task(state: MultiAgentState) -> Literal["research", "analysis", "synthesis", "end"]:
"""Route to next agent"""
if "research" not in state["results"]:
return "research"
elif "analysis" not in state["results"]:
return "analysis"
elif "synthesis" not in state["results"]:
return "synthesis"
return "end"
def route_task(state: MultiAgentState) -> Literal["research", "analysis", "synthesis", "end"]:
"""将任务路由到下一个Agent"""
if "research" not in state["results"]:
return "research"
elif "analysis" not in state["results"]:
return "analysis"
elif "synthesis" not in state["results"]:
return "synthesis"
return "end"
Build multi-agent graph
构建多Agent图
workflow = StateGraph(MultiAgentState)
workflow.add_node("research", research_agent)
workflow.add_node("analysis", analysis_agent)
workflow.add_node("synthesis", synthesis_agent)
workflow.set_entry_point("research")
workflow.add_edge("research", "analysis")
workflow.add_edge("analysis", "synthesis")
workflow.add_edge("synthesis", END)
app = workflow.compile()
workflow = StateGraph(MultiAgentState)
workflow.add_node("research", research_agent)
workflow.add_node("analysis", analysis_agent)
workflow.add_node("synthesis", synthesis_agent)
workflow.set_entry_point("research")
workflow.add_edge("research", "analysis")
workflow.add_edge("analysis", "synthesis")
workflow.add_edge("synthesis", END)
app = workflow.compile()
Execute multi-agent workflow
执行多Agent工作流
result = app.invoke({
"messages": [],
"task": "Latest trends in AI agent deployment",
"current_agent": "research",
"results": {}
})
print("Final synthesis:", result["results"]["synthesis"])
undefinedresult = app.invoke({
"messages": [],
"task": "Latest trends in AI agent deployment",
"current_agent": "research",
"results": {}
})
print("Final synthesis:", result["results"]["synthesis"])
undefined6. FastAPI Deployment
6. FastAPI部署
Deploy your agent as a REST API:
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from typing import List, Dict
import os
import uvicorn
app = FastAPI(title="Production Agent API")将Agent部署为REST API:
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from typing import List, Dict
import os
import uvicorn
app = FastAPI(title="Production Agent API")Request/Response models
请求/响应模型
class ChatRequest(BaseModel):
message: str
user_id: str
session_id: str
class ChatResponse(BaseModel):
response: str
session_id: str
metadata: Dict
class ChatRequest(BaseModel):
message: str
user_id: str
session_id: str
class ChatResponse(BaseModel):
response: str
session_id: str
metadata: Dict
Agent state
Agent状态
class AgentState(BaseModel):
messages: List[Dict]
user_id: str
session_id: str
class AgentState(BaseModel):
messages: List[Dict]
user_id: str
session_id: str
Initialize agent
初始化Agent
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
def create_agent():
"""Create agent workflow"""
def process(state: dict):
messages = state["messages"]
response = llm.invoke(messages)
state["messages"].append({
"role": "assistant",
"content": response.content
})
return state
workflow = StateGraph(dict)
workflow.add_node("process", process)
workflow.set_entry_point("process")
workflow.add_edge("process", END)
return workflow.compile()agent = create_agent()
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
def create_agent():
"""创建Agent工作流"""
def process(state: dict):
messages = state["messages"]
response = llm.invoke(messages)
state["messages"].append({
"role": "assistant",
"content": response.content
})
return state
workflow = StateGraph(dict)
workflow.add_node("process", process)
workflow.set_entry_point("process")
workflow.add_edge("process", END)
return workflow.compile()agent = create_agent()
API endpoints
API接口
@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
"""Chat endpoint"""
try:
result = agent.invoke({
"messages": [{"role": "user", "content": request.message}],
"user_id": request.user_id,
"session_id": request.session_id
})
return ChatResponse(
response=result["messages"][-1]["content"],
session_id=request.session_id,
metadata={"user_id": request.user_id}
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))@app.get("/health")
async def health():
"""Health check"""
return {"status": "healthy"}
if name == "main":
uvicorn.run(app, host="0.0.0.0", port=8000)
undefined@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
"""对话接口"""
try:
result = agent.invoke({
"messages": [{"role": "user", "content": request.message}],
"user_id": request.user_id,
"session_id": request.session_id
})
return ChatResponse(
response=result["messages"][-1]["content"],
session_id=request.session_id,
metadata={"user_id": request.user_id}
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))@app.get("/health")
async def health():
"""健康检查接口"""
return {"status": "healthy"}
if name == "main":
uvicorn.run(app, host="0.0.0.0", port=8000)
undefined7. Docker Deployment
7. Docker部署
Deploy with Docker:
dockerfile
undefined使用Docker部署:
dockerfile
undefinedDockerfile
Dockerfile
FROM python:3.11-slim
WORKDIR /app
FROM python:3.11-slim
WORKDIR /app
Install dependencies
安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
Copy application
复制应用代码
COPY . .
COPY . .
Expose port
暴露端口
EXPOSE 8000
EXPOSE 8000
Environment variables (set via docker run or docker-compose)
环境变量(通过docker run或docker-compose设置)
ENV OPENAI_API_KEY=""
ENV REDIS_URL="redis://redis:6379"
ENV OPENAI_API_KEY=""
ENV REDIS_URL="redis://redis:6379"
Run application
运行应用
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```yamlCMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```yamldocker-compose.yml
docker-compose.yml
version: '3.8'
services:
agent:
build: .
ports:
- "8000:8000"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- REDIS_URL=redis://redis:6379
- TAVILY_API_KEY=${TAVILY_API_KEY}
depends_on:
- redis
restart: unless-stopped
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
redis_data:
Deploy:
```bashversion: '3.8'
services:
agent:
build: .
ports:
- "8000:8000"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- REDIS_URL=redis://redis:6379
- TAVILY_API_KEY=${TAVILY_API_KEY}
depends_on:
- redis
restart: unless-stopped
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
redis_data:
部署命令:
```bashBuild and run
构建并运行
docker-compose up -d
docker-compose up -d
View logs
查看日志
docker-compose logs -f agent
docker-compose logs -f agent
Scale agents
扩容Agent实例
docker-compose up -d --scale agent=3
undefineddocker-compose up -d --scale agent=3
undefined8. Agent with Observability
8. 具备可观测性的Agent
Add monitoring and observability:
python
from langsmith import Client
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
import os
from datetime import datetime添加监控与可观测性:
python
from langsmith import Client
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
import os
from datetime import datetimeInitialize LangSmith
初始化LangSmith
langsmith_client = Client(api_key=os.getenv("LANGSMITH_API_KEY"))
class ObservableAgent:
def init(self, project_name: str):
self.project_name = project_name
self.llm = ChatOpenAI(
model="gpt-4",
api_key=os.getenv("OPENAI_API_KEY")
)
def create_workflow(self):
"""Create observable workflow"""
def process_with_tracing(state: dict):
# Start trace
run_id = langsmith_client.create_run(
name="agent_process",
run_type="chain",
inputs={"messages": state["messages"]},
project_name=self.project_name
)
try:
# Process
response = self.llm.invoke(state["messages"])
state["messages"].append({
"role": "assistant",
"content": response.content
})
# Log success
langsmith_client.update_run(
run_id=run_id.id,
outputs={"response": response.content},
end_time=datetime.now()
)
except Exception as e:
# Log error
langsmith_client.update_run(
run_id=run_id.id,
error=str(e),
end_time=datetime.now()
)
raise
return state
workflow = StateGraph(dict)
workflow.add_node("process", process_with_tracing)
workflow.set_entry_point("process")
workflow.add_edge("process", END)
return workflow.compile()langsmith_client = Client(api_key=os.getenv("LANGSMITH_API_KEY"))
class ObservableAgent:
def init(self, project_name: str):
self.project_name = project_name
self.llm = ChatOpenAI(
model="gpt-4",
api_key=os.getenv("OPENAI_API_KEY")
)
def create_workflow(self):
"""创建具备可观测性的工作流"""
def process_with_tracing(state: dict):
# 启动追踪
run_id = langsmith_client.create_run(
name="agent_process",
run_type="chain",
inputs={"messages": state["messages"]},
project_name=self.project_name
)
try:
# 处理请求
response = self.llm.invoke(state["messages"])
state["messages"].append({
"role": "assistant",
"content": response.content
})
# 记录成功状态
langsmith_client.update_run(
run_id=run_id.id,
outputs={"response": response.content},
end_time=datetime.now()
)
except Exception as e:
# 记录错误信息
langsmith_client.update_run(
run_id=run_id.id,
error=str(e),
end_time=datetime.now()
)
raise
return state
workflow = StateGraph(dict)
workflow.add_node("process", process_with_tracing)
workflow.set_entry_point("process")
workflow.add_edge("process", END)
return workflow.compile()Usage
使用示例
agent = ObservableAgent(project_name="production-agent")
app = agent.create_workflow()
result = app.invoke({
"messages": [{"role": "user", "content": "Hello"}]
})
agent = ObservableAgent(project_name="production-agent")
app = agent.create_workflow()
result = app.invoke({
"messages": [{"role": "user", "content": "Hello"}]
})
View traces at https://smith.langchain.com
undefinedundefinedConfiguration
配置说明
Key environment variables:
bash
undefined核心环境变量:
bash
undefinedLLM API Keys
LLM API密钥
export OPENAI_API_KEY="your-openai-key"
export ANTHROPIC_API_KEY="your-anthropic-key"
export OPENAI_API_KEY="your-openai-key"
export ANTHROPIC_API_KEY="your-anthropic-key"
Vector Stores
向量存储
export REDIS_URL="redis://localhost:6379"
export PINECONE_API_KEY="your-pinecone-key"
export REDIS_URL="redis://localhost:6379"
export PINECONE_API_KEY="your-pinecone-key"
Web Access
网页访问
export TAVILY_API_KEY="your-tavily-key"
export BRIGHTDATA_API_KEY="your-brightdata-key"
export TAVILY_API_KEY="your-tavily-key"
export BRIGHTDATA_API_KEY="your-brightdata-key"
RAG Platforms
RAG平台
export CONTEXTUAL_API_KEY="your-contextual-key"
export CONTEXTUAL_API_KEY="your-contextual-key"
Observability
可观测性
export LANGSMITH_API_KEY="your-langsmith-key"
export LANGSMITH_PROJECT="your-project-name"
export LANGSMITH_API_KEY="your-langsmith-key"
export LANGSMITH_PROJECT="your-project-name"
Security
安全防护
export ARCADE_API_KEY="your-arcade-key"
export ARCADE_API_KEY="your-arcade-key"
Deployment
部署配置
export REDIS_HOST="localhost"
export REDIS_PORT="6379"
export API_PORT="8000"
undefinedexport REDIS_HOST="localhost"
export REDIS_PORT="6379"
export API_PORT="8000"
undefinedCommon Patterns
通用模式
Agent with Tools
集成工具的Agent
python
from langchain.tools import Tool
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
import os
def calculator(expression: str) -> str:
"""Evaluate mathematical expression"""
try:
return str(eval(expression))
except:
return "Invalid expression"
def web_search(query: str) -> str:
"""Search the web"""
# Implementation with Tavily
return f"Results for: {query}"
tools = [
Tool(
name="Calculator",
func=calculator,
description="Evaluate mathematical expressions"
),
Tool(
name="WebSearch",
func=web_search,
description="Search the web for information"
)
]
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
agent = initialize_agent(
tools,
llm,
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
result = agent.run("What is 25 * 17? Then search for information about AI agents.")python
from langchain.tools import Tool
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
import os
def calculator(expression: str) -> str:
"""计算数学表达式"""
try:
return str(eval(expression))
except:
return "Invalid expression"
def web_search(query: str) -> str:
"""网页搜索"""
# 基于Tavily的实现
return f"Results for: {query}"
tools = [
Tool(
name="Calculator",
func=calculator,
description="Evaluate mathematical expressions"
),
Tool(
name="WebSearch",
func=web_search,
description="Search the web for information"
)
]
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
agent = initialize_agent(
tools,
llm,
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
result = agent.run("What is 25 * 17? Then search for information about AI agents.")Streaming Responses
流式响应
python
from langchain_openai import ChatOpenAI
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
llm = ChatOpenAI(
model="gpt-4",
api_key=os.getenv("OPENAI_API_KEY"),
streaming=True,
callbacks=[StreamingStdOutCallbackHandler()]
)python
from langchain_openai import ChatOpenAI
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
llm = ChatOpenAI(
model="gpt-4",
api_key=os.getenv("OPENAI_API_KEY"),
streaming=True,
callbacks=[StreamingStdOutCallbackHandler()]
)Stream response
流式输出响应
for chunk in llm.stream("Tell me about AI agents"):
print(chunk.content, end="", flush=True)
undefinedfor chunk in llm.stream("Tell me about AI agents"):
print(chunk.content, end="", flush=True)
undefinedError Handling and Retries
错误处理与重试
python
from tenacity import retry, stop_after_attempt, wait_exponential
from langchain_openai import ChatOpenAI
import os
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10)
)
def call_llm_with_retry(prompt: str):
"""Call LLM with automatic retries"""
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
return llm.invoke([{"role": "user", "content": prompt}])
try:
response = call_llm_with_retry("Hello, how are you?")
print(response.content)
except Exception as e:
print(f"Failed after retries: {e}")python
from tenacity import retry, stop_after_attempt, wait_exponential
from langchain_openai import ChatOpenAI
import os
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10)
)
def call_llm_with_retry(prompt: str):
"""自动重试的LLM调用"""
llm = ChatOpenAI(model="gpt-4", api_key=os.getenv("OPENAI_API_KEY"))
return llm.invoke([{"role": "user", "content": prompt}])
try:
response = call_llm_with_retry("Hello, how are you?")
print(response.content)
except Exception as e:
print(f"Failed after retries: {e}")Troubleshooting
故障排查
Common Issues
常见问题
Agent not responding:
python
undefinedAgent无响应:
python
undefinedCheck API key is set
检查API密钥是否设置
import os
assert os.getenv("OPENAI_API_KEY"), "OPENAI_API_KEY not set"
import os
assert os.getenv("OPENAI_API_KEY"), "OPENAI_API_KEY not set"
Enable verbose mode
启用 verbose 模式
from langchain.globals import set_verbose
set_verbose(True)
**Memory not persisting:**
```pythonfrom langchain.globals import set_verbose
set_verbose(True)
**存储未持久化:**
```pythonVerify Redis connection
验证Redis连接
import redis
r = redis.from_url(os.getenv("REDIS_URL", "redis://localhost:6379"))
r.ping() # Should return True
import redis
r = redis.from_url(os.getenv("REDIS_URL", "redis://localhost:6379"))
r.ping() # 应返回True
Check vector store configuration
检查向量存储配置
from langchain_redis import RedisVectorStore
from langchain_redis import RedisVectorStore
Ensure index_name is consistent across runs
确保多次运行时index_name一致
**Rate limiting:**
```python
**速率限制:**
```pythonAdd rate limiting middleware
添加速率限制中间件
from langchain.llms import OpenAI
from langchain.callbacks import get_openai_callback
with get_openai_callback() as cb:
# Your agent code here
print(f"Total Tokens: {cb.total_tokens}")
print(f"Total Cost: ${cb.total_cost}")
**Docker deployment issues:**
```bashfrom langchain.llms import OpenAI
from langchain.callbacks import get_openai_callback
with get_openai_callback() as cb:
# 你的Agent代码
print(f"Total Tokens: {cb.total_tokens}")
print(f"Total Cost: ${cb.total_cost}")
**Docker部署问题:**
```bashCheck container logs
查看容器日志
docker-compose logs -f agent
docker-compose logs -f agent
Test health endpoint
测试健康检查接口
Verify environment variables
验证环境变量
docker-compose exec agent env | grep API_KEY
**LangGraph state not updating:**
```pythondocker-compose exec agent env | grep API_KEY
**LangGraph状态未更新:**
```pythonEnsure state is properly typed
确保状态使用正确的类型
from typing import TypedDict
from langgraph.graph import StateGraph
class State(TypedDict):
messages: list # Must be mutable type
from typing import TypedDict
from langgraph.graph import StateGraph
class State(TypedDict):
messages: list # 必须是可变类型
Return updated state, don't modify in place
返回更新后的状态,不要原地修改
def node(state: State):
return {"messages": state["messages"] + [new_message]}
undefineddef node(state: State):
return {"messages": state["messages"] + [new_message]}
undefinedAdditional Resources
额外资源
Best Practices
最佳实践
- Always use environment variables for API keys and secrets
- Implement retry logic for external API calls
- Add observability from day one (LangSmith, traces)
- Use typed state in LangGraph for better debugging
- Implement health checks in production deployments
- Store conversation history in vector databases for context
- Set token limits to control costs
- Test with different LLM models for cost/performance tradeoffs
- Add input validation to prevent prompt injection
- Monitor usage and costs in production
- 始终使用环境变量存储API密钥和敏感信息
- 为外部API调用实现重试逻辑
- 从项目初期就添加可观测性(LangSmith、追踪)
- 在LangGraph中使用类型化状态,便于调试
- 在生产部署中实现健康检查
- 将对话历史存储在向量数据库中,保留上下文
- 设置令牌限制,控制成本
- 测试不同的LLM模型,平衡成本与性能
- 添加输入验证,防止提示注入
- 在生产环境中监控使用情况与成本