rdks100p上运行的模型,怎么适配langchain生态进行开发呢?

结论

要实现智能体思考与工具调用(不仅仅是问答),需要在 API 服务层之上增加 LangChain Agent 框架,核心是:封装工具函数 + 配置 Agent 执行逻辑。


智能体架构设计

┌─────────────────────────────────────────────────────────┐
│ LangChain Agent (PC/服务器)                              │
│  - ReAct/Function Calling 模式                            │
│  - 工具注册:天气查询、机器人控制、文件搜索等               │
│  - 多轮对话记忆(ConversationBufferMemory)               │
└────────────────────┬────────────────────────────────────┘
                     │ HTTP (OpenAI API)
                     ▼
┌─────────────────────────────────────────────────────────┐
│ FastAPI 桥接服务 (RDK S100P)                             │
│  - 接收 LLM 推理请求                                      │
│  - 转发给 BPU 推理引擎                                    │
│  - 返回生成结果                                          │
└────────────────────┬────────────────────────────────────┘
                     │ C++ SDK / 命令行
                     ▼
┌─────────────────────────────────────────────────────────┐
│ 官方 LLM 工具链 (BPU 加速)                                │
│  - Qwen2.5-3B HBM 模型                                   │
│  - BPU 推理加速                                          │
└─────────────────────────────────────────────────────────┘

实现步骤

:one: 先确保 API 服务正常(基础层)

参考之前帖子的 FastAPI 封装代码,确保 LangChain 能调用 S100P 的 BPU 模型:

# s100p_llm_api.py (板端运行)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import subprocess

app = FastAPI()

class ChatRequest(BaseModel):
    messages: list
    model: str = "s100p-bpu"

@app.post("/v1/chat/completions")
async def chat(req: ChatRequest):
    # 构建 prompt(根据你的模板调整)
    prompt = ""
    for msg in req.messages:
        prompt += f"{msg['role']}: {msg['content']}\n"
    
    # 调用 oellm_run(或 C++ SDK)
    cmd = [
        "./oellm_run",
        "--hbm_path", "./model/qwen2.5_3b.hbm",
        "--tokenizer_dir", "./config/",
        "--template_path", "./config/qwen.jinja",
        "--model_type", "1"
    ]
    
    result = subprocess.run(cmd, input=prompt, capture_output=True, text=True, timeout=120)
    
    return {
        "choices": [{"message": {"role": "assistant", "content": result.stdout}}]
    }

启动服务:

uvicorn s100p_llm_api:app --host 0.0.0.0 --port 8000

:two: 开发端:LangChain Agent 配置(核心)

在**开发机(PC/服务器)**上编写 Agent 代码,注册工具函数:

# agent_demo.py (开发机运行)
from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, Tool, AgentType
from langchain.memory import ConversationBufferMemory
import requests

# === 1. 定义工具函数 ===

def search_weather(city: str) -> str:
    """查询指定城市的天气"""
    # 这里可以调用真实天气 API
    return f"{city} 今天晴朗,温度 25°C"

def control_robot(action: str) -> str:
    """控制机器人执行动作(前进、后退、转向等)"""
    # 通过 ROS2/HTTP 控制机器人
    # requests.post("http://192.168.1.100:5000/control", json={"action": action})
    return f"机器人已执行:{action}"

def file_search(query: str) -> str:
    """搜索本地文档"""
    # 可以用 RAG 检索本地知识库
    return f"找到相关文档:{query}"

# === 2. 注册工具 ===
tools = [
    Tool(
        name="Weather",
        func=search_weather,
        description="查询城市天气,输入格式:城市名"
    ),
    Tool(
        name="RobotControl",
        func=control_robot,
        description="控制机器人动作,输入格式:动作名称(前进/后退/左转/右转)"
    ),
    Tool(
        name="FileSearch",
        func=file_search,
        description="搜索本地文档,输入格式:搜索关键词"
    ),
]

# === 3. 连接 S100P 的 API 服务 ===
llm = ChatOpenAI(
    base_url="http://192.168.1.100:8000/v1",  # S100P 的 IP
    api_key="not-needed",
    model="s100p-bpu",
    temperature=0.7
)

# === 4. 初始化 Agent(带记忆) ===
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,  # ReAct 模式
    memory=memory,
    verbose=True  # 打印思考过程
)

# === 5. 测试智能体 ===
if __name__ == "__main__":
    # 测试 1:工具调用
    response = agent.run("北京今天天气怎么样?")
    print(f"回答:{response}")
    
    # 测试 2:多轮对话 + 工具调用
    response = agent.run("我想让机器人前进,然后查询一下上海天气")
    print(f"回答:{response}")
    
    # 测试 3:纯对话(无需工具)
    response = agent.run("介绍一下你自己")
    print(f"回答:{response}")

:three: 智能体思考过程示例

当用户问:“北京今天天气怎么样?然后让机器人前进”

Agent 会输出以下思考过程(verbose=True 时可见):

> Entering new AgentExecutor chain...
Thought: 我需要先查询北京的天气,然后控制机器人前进
Action: Weather
Action Input: 北京
Observation: 北京 今天晴朗,温度 25°C
Thought: 天气查询完成,现在需要控制机器人
Action: RobotControl
Action Input: 前进
Observation: 机器人已执行:前进
Thought: 所有任务完成
Final Answer: 北京今天晴朗,温度 25°C。机器人已经前进。
> Finished chain.

关键功能扩展

1. 多模态智能体(视觉 + 语言)

如果要用 BPU 做视觉理解,再交给 LLM 决策:

def analyze_image(image_path: str) -> str:
    """分析图片内容(调用 BPU 视觉模型)"""
    # 1. 调用 BPU 视觉模型(YOLO/关键点检测等)
    # 2. 返回检测结果描述
    return "图片中检测到一个人,距离 2 米"

tools.append(Tool(
    name="ImageAnalysis",
    func=analyze_image,
    description="分析图片内容,输入格式:图片路径"
))

2. RAG 知识库增强

from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings

# 加载本地知识库
embeddings = HuggingFaceEmbeddings(model_name="shibing624/text2vec-base-chinese")
vectorstore = FAISS.load_local("./knowledge_base", embeddings)

tools.append(Tool(
    name="KnowledgeBase",
    func=vectorstore.similarity_search,
    description="检索本地知识库,输入格式:问题关键词"
))

3. 流式输出(打字机效果)

修改 FastAPI 支持 SSE 流式传输:

from fastapi.responses import StreamingResponse

@app.post("/v1/chat/completions/stream")
async def chat_stream(req: ChatRequest):
    def generate():
        # 逐字返回推理结果
        for token in run_inference_streaming(req.messages):
            yield f"data: {token}\n\n"
    
    return StreamingResponse(generate(), media_type="text/event-stream")

常见问题排查

问题 解决方案
Agent 不调用工具 检查 Tool 的 description 是否清晰,ReAct 模式需要明确描述
工具调用死循环 设置 max_iterations=5 限制最大尝试次数
BPU 推理慢影响体验 使用量化模型(w8a8),或异步执行工具调用
多轮对话丢失上下文 确保 ConversationBufferMemory 正确传递

建议行动路径

  1. 先跑通基础 API:确保 LangChain 能调用 S100P 的 BPU 模型
  2. 添加 1-2 个简单工具:如天气查询、文件搜索
  3. 测试 ReAct 模式:观察 Agent 思考过程
  4. 扩展多模态能力:集成 BPU 视觉模型作为工具
  5. 沉淀到社区:将完整代码发到 Model Zoo 板块

社区资源

需要我帮你写一个完整的可运行 Demo(包含 API 服务 + Agent 代码)吗?可以打包成 GitHub 仓库方便复用。