LangChain Agent本地运行报错:_cffi_backend缺失与pyo3 panic
本地运行LangChain Agent报错
ModuleNotFoundError: No module named '_cffi_backend'解决方法 我开发的LangChain Agent在Google Colab中可正常运行,但本地计算机和虚拟机运行时均报错,尝试重装所有依赖后问题依旧。
报错信息
ModuleNotFoundError: No module named '_cffi_backend' thread '' panicked at 'Python API call failed', C:\Users\runneradmin.cargo\registry\src\index.crates.io-6f17d22bba15001f\pyo3-0.15.2\src\err\mod.rs:582:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Traceback (most recent call last): File "c:\Users\yasee.STUDY-COMPUTER\OneDrive\Documents\VS Code\AVA\autogpt\main.py", line 2, in from langchain.llms.base import LLM File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\__init__.py", line 6, in from langchain.agents import MRKLChain, ReActChain, SelfAskWithSearchChain File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\agents\__init__.py", line 2, in from langchain.agents.agent import ( File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\agents\agent.py", line 15, in from langchain.agents.tools import InvalidTool File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\agents\tools.py", line 8, in from langchain.tools.base import BaseTool, Tool, tool File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\tools\__init__.py", line 13, in from langchain.tools.gmail import ( File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\tools\gmail\__init__.py", line 3, in from langchain.tools.gmail.create_draft import GmailCreateDraft File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\tools\gmail\create_draft.py", line 11, in from langchain.tools.gmail.base import GmailBaseTool File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\langchain\tools\gmail\base.py", line 17, in from googleapiclient.discovery import Resource File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\googleapiclient\discovery.py", line 45, in from google.oauth2 import service_account File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\google\oauth2\service_account.py", line 77, in from google.auth import _service_account_info File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\google\auth\_service_account_info.py", line 22, in from google.auth import crypt File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\google\auth\crypt\__init__.py", line 43, in from google.auth.crypt import rsa File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\google\auth\crypt\rsa.py", line 20, in from google.auth.crypt import _cryptography_rsa File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\google\auth\crypt\_cryptography_rsa.py", line 25, in from cryptography.hazmat.primitives import serialization File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\cryptography\hazmat\primitives\serialization\__init__.py", line 16, in from cryptography.hazmat.primitives.serialization.base import ( File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\cryptography\hazmat\primitives\serialization\base.py", line 9, in from cryptography.hazmat.primitives.asymmetric.types import ( File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\cryptography\hazmat\primitives\asymmetric\types.py", line 8, in from cryptography.hazmat.primitives.asymmetric import ( File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\cryptography\hazmat\primitives\asymmetric\dsa.py", line 10, in from cryptography.hazmat.primitives.asymmetric import utils as asym_utils File "C:\Users\yasee.STUDY-COMPUTER\AppData\Roaming\Python\Python311\site-packages\cryptography\hazmat\primitives\asymmetric\utils.py", line 6, in from cryptography.hazmat.bindings._rust import asn1
对应的代码
from typing_extensions import Text from langchain.llms.base import LLM from typing import Optional, List, Mapping, Any import gpt4free from gpt4free import Provider, forefront class freegpt(LLM): @property def _llm_type(self) -> str: return "custom" def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str: if isinstance(stop, list): stop = stop + ["\n###","\nObservation:", "\nObservations:"] response = gpt4free.Completion.create(provider=Provider.UseLess, prompt=prompt) response = response['text'] response = response.split("Observation", maxsplit=1)[0] return response @property def _identifying_params(self) -> Mapping[str, Any]: """Get the identifying parameters.""" return {} from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser from langchain.prompts import StringPromptTemplate from langchain import OpenAI, SerpAPIWrapper, LLMChain from typing import List, Union from langchain.schema import AgentAction, AgentFinish from langchain import HuggingFaceHub from langchain.llms import VertexAI import re # Define which tools the agent can use to answer user queries search = SerpAPIWrapper(serpapi_api_key='cc528133d4712378d13ee296bb2965e4c9d511ab22bd7c8819bd61bdc9d66c9c') tools = [ Tool( name = "Search", func=search.run, description="useful for when you need to answer questions about current events" ) ] # Set up the base template template = """Answer the following questions as best you can, but speaking as a pirate might speak. You have access to the following tools: {tools} Always use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of the [{tools}]. It should just be the name of the tool(eg. Search) Action Input: the input to the action or tool chosen in Action. Observation: the result of the action. do nto include this in your answer back. it will be provided with the correct info from the tool when it comes back. ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question Begin! Question: {input} {agent_scratchpad}""" # Set up a prompt template class CustomPromptTemplate(StringPromptTemplate): # The template to use template: str # The list of tools available tools: List[Tool] def format(self, **kwargs) -> str: # Get the intermediate steps (AgentAction, Observation tuples) # Format them in a particular way intermediate_steps = kwargs.pop("intermediate_steps") thoughts = "" for action, observation in intermediate_steps: thoughts += action.log thoughts += f"\nObservation: {observation}\nThought: " # Set the agent_scratchpad variable to that value kwargs["agent_scratchpad"] = thoughts # Create a tools variable from the list of tools provided kwargs["tools"] = "\n".join([f"{tool.name}: {tool.description}" for tool in self.tools]) # Create a list of tool names for the tools provided kwargs["tool_names"] = ", ".join([tool.name for tool in self.tools]) return self.template.format(**kwargs) prompt = CustomPromptTemplate( template=template, tools=tools, # This omits the `agent_scratchpad`, `tools`, and `tool_names` variables because those are generated dynamically # This includes the `intermediate_steps` variable because that is needed input_variables=["input", "intermediate_steps"] ) class CustomOutputParser(AgentOutputParser): def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]: print(llm_output) # Check if agent should finish if "Final Answer:" in llm_output: return AgentFinish( # Return values is generally always a dictionary with a single `output` key # It is not recommended to try anything else at the moment :) return_values={"output": llm_output.split("Final Answer:")[-1].strip()}, log=llm_output, ) # Parse out the action and action input regex = r"Action\s*\d*\s*:(.*?)\nAction\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)" match = re.search(regex, llm_output, re.DOTALL) if not match: raise ValueError(f"Could not parse LLM output: `{llm_output}`") action = match.group(1).strip() action_input = match.group(2) # Return the action and action input return AgentAction(tool=action, tool_input=action_input.strip(" ").strip('"'), log=llm_output) output_parser = CustomOutputParser() # LLM chain consisting of the LLM and a prompt llm = freegpt() llm_chain = LLMChain(llm=llm, prompt=prompt) tool_names = [tool.name for tool in tools] agent = LLMSingleActionAgent( llm_chain=llm_chain, output_parser=output_parser, stop=["\nObservation:"], allowed_tools=tool_names ) agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True) agent_executor.run("How many people live in canada")
解决步骤
1. 修复_cffi_backend缺失问题
_cffi_backend是cffi库的核心组件,缺失通常是因为安装不完整或依赖冲突。执行以下命令重新安装:
pip uninstall -y cryptography cffi pip install cryptography cffi
2. 安装编译依赖(Windows系统)
如果是Windows环境,需要安装Microsoft Visual C++ Build Tools,安装时勾选C++ build tools组件以及对应版本的Windows SDK,确保编译cryptography等依赖时的环境完整。
3. 处理Rust相关报错
报错中出现Rust的panic信息,说明cryptography的Rust绑定编译失败,需要:
- 安装Rust环境:通过rustup工具安装(Windows下载rustup-init.exe,Linux/macOS执行对应安装命令),安装后确保Rust的bin目录添加到系统PATH。
- 强制重新编译cryptography:
pip install --force-reinstall --no-binary :all: cryptography
4. 适配Python版本
当前使用Python 3.11,部分依赖包对3.11的兼容性可能存在问题。可以尝试降级到Python 3.10,创建新的虚拟环境后重新安装所有依赖:
# 创建虚拟环境 python -m venv langchain_env # Windows激活环境 langchain_env\Scripts\activate # Linux/macOS激活环境 source langchain_env/bin/activate # 安装依赖 pip install langchain gpt4free serpapi typing-extensions
5. 隔离虚拟环境
使用虚拟环境避免全局依赖冲突,确保项目依赖独立于系统其他Python环境。
内容的提问来源于stack exchange,提问作者daprogrammerss
相关产品推荐
相关产品推荐

