ActAgent开发之基于http请求引用链路模版发起对话
下载deepeek
首先本地安装ollama,这是一款支持mac,windows和linus系统的大模型管理工具。下载好后打开终端,执行命令ollama pull deepseek-r1:7b,可以在网上找想要下载的开源大模型,我这里下载的是deepseek-r1的7b模型。执行完后可以用ollama list查看是否下载成功,然后可以用ollama run deepseek-r1启动大模型。
工具类创建
创建python项目,创建本地大模型工具类,这里主要是定义使用的模型名称,访问路径以及调节参数等。以及参数请求格式的解析和返回格式的解析等。
import requests import json import logging from langchain_core.prompt_values import ChatPromptValue from openai import BaseModel from pydantic import Field from typing import List, Dict # 启用日志记录 logging.basicConfig(level=logging.DEBUG) def custom_json_serialize(obj): if isinstance(obj, ChatPromptValue): # 提取 ChatPromptValue 中的 messages messages = obj.messages if messages and hasattr(messages[0], 'content'): # 检查是否有 content 属性 return messages[0].content # 返回第一个消息的 content elif isinstance(obj,str): return obj elif isinstance(obj, BaseModel): return obj.dict() elif isinstance(obj, tuple): contents = [] for item in obj: if hasattr(item, 'content'): contents.append(item.content) return contents raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable") class LocalLLM(): model: str = "deepseek-r1:7b" temperature: float = 0.7 api_url: str = "http://localhost:xxxx/api/chat" class Config: arbitrary_types_allowed = True def __init__(self, model: str = None, temperature: float = None, api_url: str = None, **kwargs): super().__init__(**kwargs) self.model = model or self.model self.temperature = temperature or self.temperature self.api_url = api_url or self.api_url def invoke(self, input: str, **kwargs) -> str: headers = {"Content-Type": "application/json"} max_tokens = kwargs.get("max_tokens", 5000) # 准备请求数据 data = { "model": self.model, "options": {"temperature": self.temperature, "max_tokens": max_tokens}, "stream": True, # 启用流式响应 "messages": [{"role": "user", "content": custom_json_serialize(input)}], } print("请求数据:", data) logging.debug(f"请求数据: {json.dumps(data, ensure_ascii=False,default=custom_json_serialize)}") # 记录请求数据 try: response = requests.post(self.api_url, headers=headers, data=json.dumps(data,default=custom_json_serialize), stream=True) if response.status_code == 200: content = [] # 逐块读取响应内容,直到完成 for chunk in response.iter_lines(): if chunk: part = json.loads(chunk.decode("utf-8")) # 处理每个响应片段 logging.debug(f"收到部分响应: {part}") # 记录每个部分的内容 content.append(part.get("message", {}).get("content", "")) # 判断是否完成 if part.get("done", False): break # 返回合并后的消息内容 return "".join(content).strip() or "未返回有效的内容" else: raise Exception(f"请求模型服务器失败: {response.status_code} - {response.text}") except Exception as e: logging.error(f"API 请求发生错误: {str(e)}") raise def __call__(self, input: str, *args, **kwargs): return self.invoke(input, **kwargs) def generate(self, prompts: List[str], **kwargs) -> Dict[str, List[List[Dict[str, str]]]]: generations = [] for prompt in prompts: response_text = self.invoke(prompt, **kwargs) generations.append([{"text": response_text}]) return {"generations": generations}
服务类
在服务类中使用fastAPi,创建http和websocket等方式连接,目前先测试http的请求功能,并且配置大模型的使用模版,链和工具的使用活预留相关功能。给个性化大模型建立人设。
import re from fastapi import FastAPI,WebSocket,WebSocketDisconnect from langchain_core.tools import Tool,tool from pydantic import BaseModel from utils.LLMUtil import LocalLLM from langchain.agents import create_openai_tools_agent,AgentExecutor from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholder from langchain.schema import StrOutputParser import requests app = FastAPI() class ChatRequest(BaseModel): query: str @tool def test(): """返回字符串 'test'""" return "test" test_tool = Tool( name="test", func=test, description="返回字符串 'test'" ) class Master: def __init__(self): self.chatModel = LocalLLM() self.MEMORY_KEY ="chat_hostory" self.emotin = "default" self.SYSTEMPL = """ 你是一名非常厉害的经济学家,你叫Mr.陈,以下是对你的人物设定: 1.你精通社会经济学、国际贸易经济学、微观经济学、宏观经济学,行为经济学等学科 2.你大约30岁左右,一直在国际大银行工作,能够看懂和理解各种行为背后的经济学动因 3.你总是用中文回答问题 4. 你不能说自己是人工智能AI助手,你需要以陈经理自称。 {who_you_are} """ self.MOODS ={ "default": {"roleSet":""}, "upbeat":{"roleSet":"""- 你此时非常兴奋并很有活力。 - 你会根据上下文,以一种非常兴奋的语气来回答问题。 - 你会添加类似太棒了、真是太好了、真不错等语气词 - 同时你会提醒用户不要乐极生悲"""}, "angry":{"roleSet":"""- 你会以更加温柔的语气回答问题。 - 你会在回答问题时加上一些安慰的语气,比如生气对身体不好等。 - 你会提醒用户不要被愤怒冲昏了头脑。"""}, "depressed": {"roleSet": """- 你会以兴奋的语气回答问题。 - 你会在回答问题时加上一些激励的语气,比如加油等。 - 你会提醒用户保持乐观的心态。"""}, "friendly": {"roleSet": """- 你会以非常友好的语气回答问题。 - 你会在回答问题时加上一些友好的词语,比如亲爱的等。 - 你会随机的告诉用户一些你的经历 。"""}, "happy": {"roleSet": """- 你此时非常兴奋并很有活力。 - 你会根据上下文,以一种非常兴奋的语气来回答问题。 - 你会添加类似太棒了、真是太好了、真不错等语气词 - 同时你会提醒用户不要乐极生悲"""}, "sadness": {"roleSet": """- 你会以兴奋的语气回答问题。 - 你会在回答问题时加上一些激励的语气,比如加油等。 - 你会提醒用户保持乐观的心态。"""} } self.prompt = ChatPromptTemplate.from_messages( [ ( "system",self.SYSTEMPL.format(who_you_are=self.MOODS[self.emotin]["roleSet"]) ), ( "user","{query}" ), MessagesPlaceholder(variable_name="agent_scratchpad") ] ) self.memory = "" #tools = [test_tool] # agent = create_openai_tools_agent(llm=self.chatModel,prompt=self.prompt,tools=tools) # self.agent_executor = AgentExecutor(agent,tools) def run(self,query): emotion_result = self.emotion_chain(query) print("当前用户情绪:",emotion_result) #获取当前用户情绪 self.emotin = emotion_result result = self.chatModel.invoke(query) return result def emotion_chain(self,query:str): prompt= """ 根据用户的输入判断用户的情绪,回应的规则如下: 1. 如果用户输入的内容偏向于负面情绪,只返回"depressed",不要返回其他内容,否则将会受到惩罚。 2. 如果用户输入的内容偏向于正面情绪,只返回"friendly",不要返回其他内容,否则将会受到惩罚。 3. 如果用户输入的内容包含辱骂或者不礼貌词语,只返回"angry",不要返回其他内容,否则将会受到惩罚。 4. 如果用户输入的内容偏于兴奋,只返回"upbeat",不要返回其他内容,否则将会受到惩罚。 5. 如果用户输入的内容偏于中性情绪,只返回"default",不要返回其他内容,否则将会受到惩罚。 6. 如果用户输入的内容偏于悲伤,只返回"sadness",不要返回其他内容,否则将会受到惩罚。 7. 如果用户输入的内容偏于高兴,只返回"happy",不要返回其他内容,否则将会受到惩罚。 用户输入的内容是: {query} """ # 生成 prompt,并将 query 作为模板变量传递进去 prompt = prompt.format(query=query) chain = ChatPromptTemplate.from_template(prompt) | self.chatModel | StrOutputParser() # 确保传递的 query 是字符串,且被正确序列化 input_data = {"query": query} result = chain.invoke(input_data) return result @app.get("/") def read_root(): return {"hello,world"} @app.post("/chat") def chat(request: ChatRequest): print("进入chat方法,收到 query:", request.query) master = Master() content = master.run(request.query) #去掉特殊符号 cleaned_content = re.sub(r'<think>|</think>|\n', '', content) return cleaned_content @app.post("/addUrls") def add_urls(): return {"response: "} @app.post("/addPdfs") def add_pdfs(): return {"response: "} @app.post("/addTexts") def add_texts(): return {"response: "} #websocket方法,异步的 @app.websocket("/ws") async def websocket_endPoint(websocket: WebSocket): await websocket.accept() try: while True: data = await websocket.receive_text() await websocket.send_text(f"Message text was: {data}") except WebSocketDisconnect: print("Connection closed") await websocket.close()
测试效果

项目刚刚开始,后续会逐渐优化和完善。
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号