如何在 LangChain 中将自定义工具与 Llama 2 模型无缝集成

发布时间 - 2025-12-27 00:00:00    点击率:

本文详解如何解决 llama 2 与 langchain 自定义工具(如计算器)集成时常见的“could not parse llm output”错误,核心在于适配 llama 2 的非结构化文本输出——通过定制 outputparser 实现 json 格式指令解析,并推荐更兼容的 agent 类型。

Llama 2(尤其是 llama-2-70b-chat 等开源大模型)默认以自由文本形式生成响应,而 LangChain 的 STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION Agent 严格依赖结构化 JSON 输出(如 {"action": "Calculator", "action_input": "2 + 3"})来识别并调用工具。当 Llama 2 返回自然语言描述(例如:“我将使用计算器计算 2 加 3”)时,Agent 内置的 ReActJsonOutputParser 无法解析,从而抛出 Could not parse LLM output 错误。

✅ 正确做法是:绕过默认 parser,改用支持自由文本推理的 Agent + 自定义 OutputParser。推荐以下组合:

  1. 选用 OpenAIFunctionsAgent 或 ToolCallingAgent(LangChain v0.1+)
    这些 Agent 原生支持函数调用协议(即使后端非 OpenAI),可配合 Llama 2 的函数调用微调版本(如 llama-2-70b-chat-function-calling)或通过 prompt engineering 模拟函数调用格式。

  2. 若使用基础 Llama 2(无函数调用微调),必须自定义 OutputParser
    示例代码(基于 llama-cpp-python 或 transformers 加载模型):

from langchain_core.output_parsers import BaseOutputParser
from langchain_core.agents import AgentAction, AgentFinish
import re
import json

class Llama2ReActOutputParser(BaseOutputParser):
    def parse(self, text: str) -> AgentAction | AgentFinish:
        # 匹配 Llama 2 常见的 ReAct 风格输出(支持中文/英文混合)
        if "Final Answer:" in text:
            return AgentFinish(return_values={"output": text.split("Final Answer:")[-1].strip()}, log=text)

        # 尝试提取 action 和 action_input(兼容多种格式)
        action_match = re.search(r"Action:\s*(\w+)", text)
        input_match = re.search(r"Action Input:\s*(.*)", text, re.DOTALL)

        if action_match and input_match:
            action = action_match.group(1).strip()
            action_input = input_match.group(1).strip().strip('"\'')
            try:
                # 尝试 JSON 解析 action_input(如为 JSON 字符串)
                parsed_input = json.loads(action_input)
                return AgentAction(tool=action, tool_input=parsed_input, log=text)
            except (json.JSONDecodeError, ValueError):
                return AgentAction(tool=action, tool_input=action_input, log=text)

        raise ValueError(f"Could not parse LLM output: {text}")

# 使用示例
from langchain_community.llms import LlamaCpp
from langchain.agents import AgentExecutor, create_structured_chat_agent

llm = LlamaCpp(
    model_path="./models/llama-2-70b-chat.Q4_K_M.gguf",
    temperature=0.1,
    max_tokens=512,
    top_p=1,
    verbose=False,
)

# 自定义工具(如 Calculator)
from langchain.tools import StructuredTool
def calculate(expression: str) -> str:
    try:
        return str(eval(expression))
    except:
        return "Invalid expression"

calculator = StructuredTool.from_function(
    func=calculate,
    name="Calculator",
    description="Useful for performing arithmetic calculations. Input must be a valid Python expression (e.g., '2 + 3 * 4')."
)

prompt = hub.pull("hwchase17/structured-chat-agent")
agent = create_structured_chat_agent(
    llm=llm,
    tools=[calculator],
    prompt=prompt,
    output_parser=Llama2ReActOutputParser()  # 关键:注入自定义 parser
)

agent_executor = AgentExecutor(agent=agent, tools=[calculator], verbose=True)

⚠️ 注意事项:

  • Prompt 工程至关重要:确保使用的 Prompt 模板(如 hwchase17/structured-chat-agent)明确要求 Llama 2 以 Action: / Action Input: / Final Answer: 格式输出,避免自由发挥。
  • 避免 STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 直接搭配原生 Llama 2:该 Agent 对输出格式容错性极低,建议优先尝试 create_openai_functions_agent(配合 llm.bind_tools())或升级至 LangChain 0.1.20+ 的 create_tool_calling_agent。
  • 多输入工具支持:StructuredTool 天然支持 Pydantic 模型定义多参数(如 def search(query: str, site: str, timeout: int = 5)),无需额外配置;Agent 会自动解析结构化输入。

总结:Llama 2 与 LangChain 工具链集成失败,本质是“LLM 输出格式”与“Agent 解析协议”不匹配。解决方案不是更换模型,而是精准定制 OutputParser + 选择语义兼容的 Agent 类型 + 强化 Prompt 约束。参考 Pinecone 官方 Llama 2 Agent 示例 可快速验证完整流程。


# react  # python  # js  # json  # seo  # 工具  # 后端  # mac  # ai  # openai  # 大模型  # red 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何记录自定义日志?(Log频道配置)  公司网站制作需要多少钱,找人做公司网站需要多少钱?  Laravel怎么清理缓存_Laravel optimize clear命令详解  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  Angular 表单中正确绑定输入值以确保提交与验证正常工作  ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】  网站建设整体流程解析,建站其实很容易!  iOS验证手机号的正则表达式  如何在IIS中新建站点并解决端口绑定冲突?  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  网站制作软件免费下载安装,有哪些免费下载的软件网站?  网站制作大概多少钱一个,做一个平台网站大概多少钱?  WEB开发之注册页面验证码倒计时代码的实现  Laravel如何发送系统通知?(Notification渠道示例)  如何用虚拟主机快速搭建网站?详细步骤解析  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  IOS倒计时设置UIButton标题title的抖动问题  C#如何调用原生C++ COM对象详解  Python3.6正式版新特性预览  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  如何制作一个表白网站视频,关于勇敢表白的小标题?  如何快速生成可下载的建站源码工具?  Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  如何打造高效商业网站?建站目的决定转化率  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  如何实现javascript表单验证_正则表达式有哪些实用技巧  phpredis提高消息队列的实时性方法(推荐)  个人摄影网站制作流程,摄影爱好者都去什么网站?  高防服务器租用指南:配置选择与快速部署攻略  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  如何在建站宝盒中设置产品搜索功能?  如何在香港免费服务器上快速搭建网站?  如何在腾讯云服务器上快速搭建个人网站?  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  大型企业网站制作流程,做网站需要注册公司吗?  如何在万网自助建站中设置域名及备案?  Laravel安装步骤详细教程_Laravel环境搭建指南  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  Firefox Developer Edition开发者版本入口  如何在阿里云虚拟服务器快速搭建网站?  制作电商网页,电商供应链怎么做?  如何用PHP快速搭建CMS系统?  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用