{"id":53719,"date":"2025-02-16T17:07:56","date_gmt":"2025-02-16T09:07:56","guid":{"rendered":"https:\/\/fwq.ai\/blog\/53719\/"},"modified":"2025-02-16T17:07:56","modified_gmt":"2025-02-16T09:07:56","slug":"deepseek-ai%e9%a9%b1%e5%8a%a8%e7%9a%84react%e4%bb%a3%e7%90%86","status":"publish","type":"post","link":"https:\/\/fwq.ai\/blog\/53719\/","title":{"rendered":"DeepSeek AI\u9a71\u52a8\u7684ReAct\u4ee3\u7406"},"content":{"rendered":"<p>\u65e0\u8bba\u4f60\u5bf9DeepSeek\u6709\u4f55\u770b\u6cd5\uff0c\u5b83\u73b0\u5728\u5df2\u7ecf\u5728\u6e38\u620f\u4e2d\u4e86\uff0c\u5e76\u4e14\u662f\u4e00\u4e2a\u503c\u5f97\u8bc4\u4f30\u7684\u5b9e\u7528\u9009\u9879\uff01\u4e3a\u4e86\u505a\u51fa\u660e\u667a\u7684\u51b3\u7b56\uff0c\u5728\u7279\u5b9a\u9700\u6c42\u80cc\u666f\u4e0b\u8bc4\u4f30DeepSeek\u4e0e\u5176\u4ed6LLM\u3002<\/p>\n<p>\u5728\u8fd9\u7bc7\u6587\u7ae0\uff08\u4ee5\u53ca\u76f8\u5e94\u7684\uff09\u4e2d\uff0c\u6211\u5c06\u5f15\u5bfc\u4f60\u5982\u4f55\u5728Vertex AI\u7aef\u70b9\u4e0a\u90e8\u7f72DeepSeek\u6a21\u578b\u5e76\u4f7f\u7528Langchain\u6784\u5efaReAct Agent\uff0c\u4ee5\u4fbf\u4f60\u53ef\u4ee5\u8bc4\u4f30\u5176\u6027\u80fd\u3002<\/p>\n<p><strong>\u6784\u5efa\u81ea\u5b9a\u4e49LLM\u5305\u88c5\u5668<\/strong><\/p>\n<p>\u4e3a\u4e86\u8fde\u63a5Vertex AI\u4e0a\u7684DeepSeek\u548cLangChain\u6846\u67b6\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u4e00\u4e2a\u81ea\u5b9a\u4e49LLM\u5305\u88c5\u5668\uff1a<\/p>\n<pre><code>class CustomLLM(LLM):  \n    model_name: str = Field(default=\"vertex-ai\")  \n    generation_config: Dict[str, Any] = Field(default_factory=dict)  \n  \n    @property  \n    def _llm_type(self) -&gt; str:  \n        return \"custom-vertex-ai\"  \n  \n    def _call(self, prompt: str, stop: Optional[List[str]] = None) -&gt; str:  \n        prediction_request = {  \n            \"instances\": [  \n                {  \n                    \"@requestFormat\": \"textGeneration\",  \n                    \"prompt\": prompt,  \n                    \"maxOutputTokens\": self.generation_config.get(\"max_output_tokens\", 2048),  \n                    \"temperature\": self.generation_config.get(\"temperature\", 0.8),  \n                    \"candidateCount\": self.generation_config.get(\"candidate_count\", 1),  \n                }  \n            ]  \n        }  \n        response = endpoint.predict(instances=prediction_request[\"instances\"])  \n        return response.predictions[0] if response.predictions else \"\"\n<\/code><\/pre>\n<p>\u8fd9\u4e2a<code>CustomLLM<\/code>\u7c7b\u5c01\u88c5\u4e86\u4e0eVertex AI\u7aef\u70b9\u7684\u4ea4\u4e92\uff0c\u5141\u8bb8\u6211\u4eec\u914d\u7f6e\u53c2\u6570\u5982<code>max_output_tokens<\/code>\u3001<code>temperature<\/code>\u548c<code>candidate_count<\/code>\u3002<\/p>\n<p><strong>\u5b9e\u73b0ReAct Agent\u6267\u884c\u5668<\/strong><\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u521b\u5efa\u4e00\u4e2a<code>ReActAgentExecutor<\/code>\u6765\u534f\u8c03\u4ee3\u7406\u7684\u884c\u4e3a\uff1a<\/p>\n<pre><code>class ReActAgentExecutor:  \n    \"\"\"  \n    \u4e00\u4e2a\u7528\u4e8e\u8fd0\u884c\u5177\u6709\u6307\u5b9a\u914d\u7f6e\u548c\u5de5\u5177\u7684ReAct\u4ee3\u7406\u7684\u7c7b\u3002  \n    \"\"\"  \n    def __init__(  \n        self,  \n        model: str,  \n        generation_config: Dict,  \n        max_iterations: int,  \n        max_execution_time: int,  \n        google_api_key: str=GOOGLE_API_KEY,  \n        cse_id: str=CSE_ID,  \n    ):  \n        self.model = model  \n        self.generation_config = generation_config  \n        self.max_iterations = max_iterations  \n        self.max_execution_time = max_execution_time  \n        self.google_api_key = google_api_key  \n        self.cse_id = cse_id  \n        self.llm = None  \n        self.tools = None  \n        self.agent = None  \n        self.agent_executor = None  \n        self.token_callback = None  \n  \n        self._setup_llm()  \n        self._setup_tools()  \n        self._setup_agent()  \n  \n    def _setup_llm(self):  \n        \"\"\"\u521d\u59cb\u5316\u81ea\u5b9a\u4e49LLM.\"\"\"  \n        self.llm = CustomLLM(model=self.model, generation_config=self.generation_config)  \n  \n    def _setup_tools(self):  \n        \"\"\"\u8bbe\u7f6e\u4ee3\u7406\u7684\u5de5\u5177.\"\"\"  \n        search = GoogleSearchAPIWrapper(  \n            google_api_key=self.google_api_key, google_cse_id=self.cse_id  \n        )  \n        self.tools = [  \n            Tool(  \n                name=\"Google Search\",  \n                func=search.run,  \n                description=\"\u7528\u4e8e\u67e5\u627e\u5f53\u524d\u4e8b\u4ef6\u3001\u6bd4\u8f83\u6216\u4e0d\u540c\u89c2\u70b9\u7684\u4fe1\u606f\u3002\",  \n            ),  \n        ]  \n  \n    def _setup_agent(self):  \n        \"\"\"\u8bbe\u7f6eReAct\u4ee3\u7406\u548c\u6267\u884c\u5668.\"\"\"  \n        prompt = hub.pull(\"hwchase17\/react\")  \n        system_instruction = \"\u4e00\u65e6\u627e\u5230\u7b54\u6848\uff0c\u8bf7\u53ea\u8fd4\u56deYes\u6216No\"  \n        prompt.template = system_instruction + \"\\n\" + prompt.template  \n  \n        self.agent = create_react_agent(self.llm, self.tools, prompt)  \n        self.token_callback = TokenCountingCallbackHandler(self.model)  \n        self.agent_executor = AgentExecutor(  \n            agent=self.agent,  \n            tools=self.tools,  \n            verbose=False,  \n            handle_parsing_errors=True,  \n            max_iterations=self.max_iterations,  \n            max_execution_time=self.max_execution_time,  \n            callbacks=[self.token_callback],  \n        )  \n  \n    def run(self, input_data: Union[Dict, str]) -&gt; Dict:  \n        \"\"\"  \n        \u4f7f\u7528\u7ed9\u5b9a\u8f93\u5165\u6570\u636e\u8fd0\u884c\u4ee3\u7406\u3002  \n        \"\"\"  \n        if isinstance(input_data, str):  \n            input_data = {\"input\": input_data}  \n  \n        start_time = time.time()  \n        try:  \n            result = self.agent_executor.invoke(input_data)  \n            result[\"total_token\"] = self.token_callback.total_token  \n            self.token_callback.reset()  \n        except Exception as e:  \n            print(f\"\u53d1\u751f\u9519\u8bef\uff1a{e}\")  \n            result = {\"error\": str(e)}  \n        end_time = time.time()  \n        result[\"wall_time\"] = end_time - start_time  \n  \n        return result\n<\/code><\/pre>\n<p><strong>\u4ee4\u724c\u8ba1\u6570\u56de\u8c03\u5904\u7406\u5668<\/strong><\/p>\n<pre><code>class TokenCountingCallbackHandler(BaseCallbackHandler):  \n    \"\"\"\u8bed\u8a00\u6a21\u578b\u4f7f\u7528\u7684\u4ee4\u724c\u8ba1\u6570\u56de\u8c03\u5904\u7406\u5668\u3002\"\"\"  \n    def __init__(self, model_name: str):  \n        self.model_name = model_name  \n        self.total_token = 0  \n  \n    def reset(self):  \n        \"\"\"\u91cd\u7f6e\u4e0b\u4e00\u4e2a\u94fe\u8fd0\u884c\u7684\u8ba1\u6570\u5668\u3002\"\"\"  \n        self.total_token = 0\n<\/code><\/pre>\n<p>\u6b64\u56de\u8c03\u5904\u7406\u5668\u63d0\u4f9b\u4e86\u4ee3\u7406\u6267\u884c\u671f\u95f4\u4ee4\u724c\u6d88\u8017\u7684\u6d1e\u5bdf\uff0c\u8fd9\u5bf9\u4e8e\u6210\u672c\u4f18\u5316\u975e\u5e38\u6709\u4ef7\u503c\u3002<\/p>\n<p><strong>\u6574\u5408\u6240\u6709\u5185\u5bb9<\/strong><\/p>\n<p>\u901a\u8fc7\u7ed3\u5408DeepSeek\u6a21\u578b\u3001Vertex AI\u548cReAct\u4ee3\u7406\u6846\u67b6\uff0c\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u5f3a\u5927\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u80fd\u591f\u5904\u7406\u590d\u6742\u4efb\u52a1\u3002\u672c\u6559\u7a0b\u63d0\u4f9b\u4e86\u4e00\u4e2a\u8fdb\u4e00\u6b65\u63a2\u7d22\u548c\u5b9e\u9a8c\u7684\u57fa\u7840\u3002<\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>\u65e0\u8bba\u4f60\u5bf9DeepSeek\u6709\u4f55\u770b\u6cd5\uff0c\u5b83\u73b0\u5728\u5df2\u7ecf\u5728\u6e38\u620f\u4e2d\u4e86\uff0c\u5e76\u4e14\u662f\u4e00\u4e2a\u503c\u5f97\u8bc4\u4f30\u7684\u5b9e\u7528\u9009\u9879\uff01\u4e3a\u4e86\u505a\u51fa\u660e\u667a\u7684\u51b3\u7b56\uff0c\u5728\u7279\u5b9a\u9700\u6c42\u80cc\u666f\u4e0b\u8bc4\u4f30DeepSeek\u4e0e\u5176\u4ed6LLM\u3002 \u5728\u8fd9\u7bc7\u6587\u7ae0\uff08\u4ee5\u53ca\u76f8\u5e94\u7684\uff09\u4e2d\uff0c\u6211\u5c06\u5f15\u5bfc\u4f60\u5982\u4f55\u5728Vertex AI\u7aef\u70b9\u4e0a\u90e8\u7f72DeepSeek\u6a21\u578b\u5e76\u4f7f\u7528Langchain\u6784\u5efaReAct Agent\uff0c\u4ee5\u4fbf\u4f60\u53ef\u4ee5\u8bc4\u4f30\u5176\u6027\u80fd\u3002 \u6784\u5efa\u81ea\u5b9a\u4e49LLM\u5305\u88c5\u5668 \u4e3a\u4e86\u8fde\u63a5Vertex AI\u4e0a\u7684DeepSeek\u548cLangChain\u6846\u67b6\uff0c\u6211\u4eec\u9996\u5148\u521b\u5efa\u4e00\u4e2a\u81ea\u5b9a\u4e49LLM\u5305\u88c5\u5668\uff1a class CustomLLM(LLM): model_name: str = Field(default=&#8221;vertex-ai&#8221;) generation_config: Dict[str, Any] = Field(default_factory=dict) @property def _llm_type(self) -&gt; str: return &#8220;custom-vertex-ai&#8221; def _call(self, prompt: str, stop: Optional[List[str]] = None) -&gt; str: prediction_request = { &#8220;instances&#8221;: [ { &#8220;@requestFormat&#8221;: &#8220;textGeneration&#8221;, &#8220;prompt&#8221;: prompt, &#8220;maxOutputTokens&#8221;: self.generation_config.get(&#8220;max_output_tokens&#8221;, 2048), &#8220;temperature&#8221;: self.generation_config.get(&#8220;temperature&#8221;, 0.8), &#8220;candidateCount&#8221;: self.generation_config.get(&#8220;candidate_count&#8221;, 1), } [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-53719","post","type-post","status-publish","format-standard","hentry","category-ai"],"_links":{"self":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/53719","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/comments?post=53719"}],"version-history":[{"count":0,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/53719\/revisions"}],"wp:attachment":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/media?parent=53719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/categories?post=53719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/tags?post=53719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}